function print_fams($person, $famid = null) { global $pgv_lang, $surn, $surn_lang, $TEXT_DIRECTION; // select person name according to searched surname $person_name = ""; foreach ($person->getAllNames() as $n => $name) { list($surn1) = explode(", ", $name['list']); if (stripos($surn1, $surn) === false && stripos($surn, $surn1) === false && soundex_std($surn1) !== soundex_std($surn) && soundex_dm($surn1) !== soundex_dm($surn)) { continue; } if (whatLanguage($surn1) !== $surn_lang) { continue; } $person_name = $name['full']; break; } if (empty($person_name)) { echo "<span title=\"", PrintReady(strip_tags($person->getFullName())), "\">", $person->getSexImage(), "...</span>"; return; } $person_lang = whatLanguage($person_name); // current indi echo "<li>"; $class = ""; $sosa = @array_search($person->getXref(), $_SESSION['user_ancestors']); if ($sosa) { $class = "search_hit"; $sosa = "<a dir={$TEXT_DIRECTION} target=\"_blank\" class=\"details1 {$person->getBoxStyle()}\" title=\"Sosa\" href=\"relationship.php?pid2=" . PGV_USER_ROOT_ID . "&pid1=" . $person->getXref() . "\"> {$sosa} </a>" . sosa_gen($sosa); } $current = $person->getSexImage() . "<a target=\"_blank\" class=\"{$class}\" title=\"" . $person->getXref() . "\" href=\"{$person->getLinkUrl()}\">" . PrintReady($person_name) . "</a> " . $person->getBirthDeathYears() . " {$sosa}"; if ($famid && $person->getChildFamilyPedigree($famid)) { $current = "<span class='red'>" . $pgv_lang[$person->getChildFamilyPedigree($famid)] . "</span> " . $current; } // spouses and children if (count($person->getSpouseFamilies()) < 1) { echo $current; } foreach ($person->getSpouseFamilies() as $f => $family) { $txt = $current; $spouse = $family->getSpouse($person); if ($spouse) { $class = ""; $sosa2 = @array_search($spouse->getXref(), $_SESSION['user_ancestors']); if ($sosa2) { $class = "search_hit"; $sosa2 = "<a dir={$TEXT_DIRECTION} target=\"_blank\" class=\"details1 {$spouse->getBoxStyle()}\" title=\"Sosa\" href=\"relationship.php?pid2=" . PGV_USER_ROOT_ID . "&pid1=" . $spouse->getXref() . "\"> {$sosa2} </a>" . sosa_gen($sosa2); } if ($family->getMarriageYear()) { $txt .= " <span dir={$TEXT_DIRECTION} class='details1' title=\"" . strip_tags($family->getMarriageDate()->Display()) . "\">" . PGV_ICON_RINGS . $family->getMarriageYear() . "</span> "; } else { if ($family->getMarriage()) { $txt .= " <span dir={$TEXT_DIRECTION} class='details1' title=\"" . $pgv_lang["yes"] . "\">" . PGV_ICON_RINGS . "</span> "; } } $spouse_name = $spouse->getListName(); foreach ($spouse->getAllNames() as $n => $name) { if (whatLanguage($name['list']) == $person_lang) { $spouse_name = $name['list']; break; } else { if ($name['fullNN'] == "@P.N. @N.N.") { $spouse_name = $pgv_lang["NN" . $person_lang] . ", " . $pgv_lang["NN" . $person_lang]; break; } } } list($surn2, $givn2) = explode(", ", $spouse_name . ", x"); $txt .= $spouse->getSexImage() . "<a target=\"_blank\" class=\"{$class}\" title=\"" . $family->getXref() . "\" href=\"{$family->getLinkUrl()}\">" . PrintReady($givn2) . "</a> " . "<a class=\"{$class}\" title=\"{$surn2}\" href=\"javascript:document.surnlist.surn.value='{$surn2}';document.surnlist.submit();\">" . PrintReady($surn2) . "</a> " . $spouse->getBirthDeathYears() . " {$sosa2}"; } echo $txt; echo "<ol>"; foreach ($family->getChildren() as $c => $child) { print_fams($child, $family->getXref()); } echo "</ol>"; } echo "</li>"; }
function getSecondaryName() { if (is_null($this->_getSecondaryName)) { // Generally, the primary and secondary names are the same $this->_getSecondaryName = $this->getPrimaryName(); // ....except when there are names with different character sets $all_names = $this->getAllNames(); if (count($all_names) > 1) { $primary_language = whatLanguage($all_names[$this->getPrimaryName()]['sort']); foreach ($all_names as $n => $name) { if ($n != $this->getPrimaryName() && $name['type'] != '_MARNM' && whatLanguage($name['sort']) != $primary_language) { $this->_getSecondaryName = $n; break; } } } } return $this->_getSecondaryName; }
function getAllNames() { if (is_null($this->_getAllNames)) { $husb = $this->husb ? $this->husb : new Person('1 SEX M'); $wife = $this->wife ? $this->wife : new Person('1 SEX F'); // Check the script used by each name, so we can match cyrillic with cyrillic, greek with greek, etc. $husb_names = $husb->getAllNames(); foreach ($husb_names as $n => $husb_name) { $husb_names[$n]['lang'] = whatLanguage($husb_name['surn']); } $wife_names = $wife->getAllNames(); foreach ($wife_names as $n => $wife_name) { $wife_names[$n]['lang'] = whatLanguage($wife_name['surn']); } // Add the matched names first foreach ($husb_names as $husb_name) { foreach ($wife_names as $wife_name) { if ($husb_name['type'] != '_MARNM' && $wife_name['type'] != '_MARNM' && $husb_name['lang'] == $wife_name['lang']) { $this->_getAllNames[] = array('type' => $husb_name['type'], 'full' => $husb_name['full'] . ' + ' . $wife_name['full'], 'list' => $husb_name['list'] . $husb->getSexImage() . '<br />' . $wife_name['list'] . $wife->getSexImage(), 'sort' => $husb_name['sort'] . ' + ' . $wife_name['sort']); } } } // Add the unmatched names second (there may be no matched names) foreach ($husb_names as $husb_name) { foreach ($wife_names as $wife_name) { if ($husb_name['type'] != '_MARNM' && $wife_name['type'] != '_MARNM' && $husb_name['lang'] != $wife_name['lang']) { $this->_getAllNames[] = array('type' => $husb_name['type'], 'full' => $husb_name['full'] . ' + ' . $wife_name['full'], 'list' => $husb_name['list'] . $husb->getSexImage() . '<br />' . $wife_name['list'] . $wife->getSexImage(), 'sort' => $husb_name['sort'] . ' + ' . $wife_name['sort']); } } } } return $this->_getAllNames; }
function _addName($type, $full, $gedrec) { global $UNDERLINE_NAME_QUOTES, $NAME_REVERSE, $unknownNN, $unknownPN, $pgv_lang; // Look for GIVN/SURN at level n+1 $sublevel = 1 + (int) $gedrec[0]; // Fix bad slashes. e.g. "John/Smith" => "John/Smith/" if (substr_count($full, '/') % 2 == 1) { $full .= '/'; } // Need the GIVN and SURN to generate the sortable name. $givn = preg_match("/\n{$sublevel} GIVN (.+)/", $gedrec, $match) ? $match[1] : ''; $surn = preg_match("/\n{$sublevel} SURN (.+)/", $gedrec, $match) ? $match[1] : ''; $spfx = preg_match("/\n{$sublevel} SPFX (.+)/", $gedrec, $match) ? $match[1] : ''; if ($givn || $surn) { // An empty surname won't have a SURN field if (strpos($full, '//')) { $surn = '@N.N.'; } // GIVN and SURN can be comma-separated lists. $surns = preg_split('/ *, */', $surn); $givn = str_replace(array(', ', ','), ' ', $givn); // SPFX+SURN for lists $surn = ($spfx ? $spfx . ' ' : '') . $surn; } else { $name = $full; // We do not have a structured name - extract the GIVN and SURN(s) ourselves // Strip the NPFX if (preg_match('/^(?:(?:(?:ADM|AMB|BRIG|CAN|CAPT|CHAN|CHAPLN|CMDR|COL|CPL|CPT|DR|GEN|GOV|HON|LADY|LORD|LT|MR|MRS|MS|MSGR|PFC|PRES|PROF|PVT|RABBI|REP|REV|SEN|SGT|SIR|SR|SRA|SRTA|VEN)\\.? +)+)(.+)/i', $name, $match)) { $name = $match[1]; } // Strip the NSFX if (preg_match('/(.+)(?:(?: +(?:ESQ|ESQUIRE|JR|JUNIOR|SR|SENIOR|[IVX]+)\\.?)+)$/i', $name, $match)) { $name = $match[1]; } // Extract GIVN/SURN. if (strpos($full, '/') === false) { $givn = trim($name); $spfx = ''; $surns = array(''); } else { // Extract SURN. Split at "/". Odd numbered parts are SURNs. $spfx = ''; $surns = array(); foreach (preg_split(': */ *:', $name) as $key => $value) { if ($key % 2 == 1) { if ($value) { // Strip SPFX if (preg_match('/^((?:(?:A|AAN|AB|AF|AL|AP|AS|AUF|AV|BAT|BIJ|BIN|BINT|DA|DE|DEL|DELLA|DEM|DEN|DER|DI|DU|EL|FITZ|HET|IBN|LA|LAS|LE|LES|LOS|ONDER|OP|OVER|\'S|ST|\'T|TE|TEN|TER|TILL|TOT|UIT|UIJT|VAN|VANDEN|VON|VOOR|VOR) )+(?:[DL]\')?)(.+)$/i', $value, $match)) { $spfx = trim($match[1]); $value = $match[2]; } $surns[] = $value ? $value : '@N.N.'; } else { $surns[] = '@N.N.'; } } } // SPFX+SURN for lists $surn = ($spfx ? $spfx . ' ' : '') . implode(' ', $surns); // Extract the GIVN. Before first "/" and after last. $pos1 = strpos($name, '/'); if ($pos1 === false) { $givn = $name; } else { $pos2 = strrpos($name, '/'); $givn = trim(substr($name, 0, $pos1) . ' ' . substr($name, $pos2 + 1)); } } } // Tidy up whitespace $full = preg_replace('/ +/', ' ', trim($full)); // Add placeholder for unknown surname if (preg_match(':/ */:', $full)) { $full = preg_replace(':/ */:', '/@N.N./', $full); } // Add placeholder for unknown given name if (!$givn) { $givn = '@P.N.'; $pos = strpos($full, '/'); $full = substr($full, 0, $pos) . '@P.N. ' . substr($full, $pos); } // Some systems don't include the NPFX in the NAME record. $npfx = preg_match('/^' . $sublevel . ' NPFX (.+)/m', $gedrec, $match) ? $match[1] : ''; if ($npfx && stristr($full, $npfx) === false) { $full = $npfx . ' ' . $full; } // Make sure the NICK is included in the NAME record. if (preg_match('/^' . $sublevel . ' NICK (.+)/m', $gedrec, $match)) { $pos = strpos($full, '/'); if ($pos === false) { $full .= ' "' . $match[1] . '"'; } else { $full = substr($full, 0, $pos) . '"' . $match[1] . '" ' . substr($full, $pos); } } // Convert "user-defined" unknowns into PGV unknowns $full = preg_replace('/\\/(_+|\\?+|-+)\\//', '/@N.N./', $full); $full = preg_replace('/(?<= |^)(_+|\\?+|-+)(?= |$)/', '@P.N.', $full); $surn = preg_replace('/^(_+|\\?+|-+)$/', '@N.N.', $surn); $givn = preg_replace('/(?<= |^)(_+|\\?+|-+)(?= |$)/', '@P.N.', $givn); foreach ($surns as $key => $value) { $surns[$key] = preg_replace('/^(_+|\\?+|-+)$/', '@N.N.', $value); } // Create the list (surname first) version of the name. Note that zero // slashes are valid; they indicate NO surname as opposed to missing surname. $pos1 = strpos($full, '/'); if ($pos1 === false) { $list = $full; } else { $pos2 = strrpos($full, '/'); $list = trim(substr($full, $pos1 + 1, $pos2 - $pos1 - 1)) . ', ' . substr($full, 0, $pos1) . substr($full, $pos2 + 1); $list = trim(str_replace(array('/', ' '), array('', ' '), $list)); $full = trim(str_replace(array('/', ' '), array('', ' '), $full)); } // Need the "not known" place holders for the database $fullNN = $full; $listNN = $list; $surname = $surn; // Hungarians want the "full" name to be the surname first (i.e. "list") variant if ($NAME_REVERSE) { $full = $list; } // Some people put preferred names in quotes if ($UNDERLINE_NAME_QUOTES) { $full = preg_replace('/"([^"]*)"/', '<span class="starredname">\\1</span>', $full); $list = preg_replace('/"([^"]*)"/', '<span class="starredname">\\1</span>', $list); } // The standards say you should use a suffix of "*" $full = preg_replace('/(\\S*)\\*/', '<span class="starredname">\\1</span>', $full); $list = preg_replace('/(\\S*)\\*/', '<span class="starredname">\\1</span>', $list); // If the name is written in greek/cyrillic/hebrew/etc., use the "unknown" name // from that character set. Otherwise use the one in the language file. if (strpos($givn, '@P.N.') !== false || $surn == '@N.N.' || $surns[0] == '@N.N.') { if (strpos($givn, '@P.N.') !== false && ($surn == '@N.N.' || $surns[0] == '@N.N.')) { $PN = $pgv_lang['PN']; $NN = $pgv_lang['NN']; } else { if ($surn !== '') { $PN = $unknownPN[whatLanguage($surn)]; } else { $PN = $unknownPN[whatLanguage($surns[0])]; } $NN = $unknownNN[whatLanguage($givn)]; } $list = str_replace(array('@N.N.', '@P.N.'), array($NN, $PN), $list); $full = str_replace(array('@N.N.', '@P.N.'), array($NN, $PN), $full); } // A comma separated list of surnames (from the SURN, not from the NAME) indicates // multiple surnames (e.g. Spanish). Each one is a separate sortable name. // Where nicknames are entered in the given name field, these will break // sorting, so strip them out. $GIVN = preg_replace('/["\'()]/', '', UTF8_strtoupper($givn)); foreach ($surns as $n => $surn) { $SURN = UTF8_strtoupper($surn); // Scottish "Mc and Mac" prefixes sort under "Mac" if (substr($SURN, 0, 2) == 'MC') { $SURN = 'MAC' . substr($SURN, 2); } if (substr($SURN, 0, 4) == 'MAC ') { $SURN = 'MAC' . substr($SURN, 4); } $this->_getAllNames[] = array('type' => $type, 'full' => $full, 'list' => $list, 'sort' => $SURN . ',' . $GIVN, 'fullNN' => $fullNN, 'listNN' => $listNN, 'surname' => $surname, 'givn' => $givn, 'spfx' => $n ? '' : $spfx, 'surn' => $SURN); } }