/** * is the person alive in the given year * @param string $indirec the persons raw gedcom record * @param int $year the year to check if they are alive in * @return int return 0 if the person is alive, negative number if they died earlier, positive number if they will be born in the future */ function check_alive($indirec, $year) { global $MAX_ALIVE_AGE; if (is_dead($indirec, $year)) { return -1; } // Died before year? $deathrec = get_sub_record(1, "1 DEAT", $indirec); if (preg_match("/\\d DATE (.*)/", $deathrec, $match)) { $ddate = new GedcomDate($match[1]); $dyear = $ddate->gregorianYear(); if ($year > $dyear) { return -1; } } // Born after year? $birthrec = get_sub_record(1, "1 BIRT", $indirec); if (preg_match("/\\d DATE (.*)/", $birthrec, $match)) { $bdate = new GedcomDate($match[1]); $byear = $bdate->gregorianYear(); if ($year < $byear) { return 1; } } // Born before year and died after year if (isset($byear) && isset($dyear) && $year >= $byear && $year <= $dyear) { return 0; } // If no death record than check all dates; $years = array(); $subrecs = get_all_subrecords($indirec, "CHAN", true, true, false); foreach ($subrecs as $ind => $subrec) { if (preg_match("/\\d DATE (.*)/", $subrec, $match)) { $date = new GedcomDate($match[1]); $datey = $date->gregorianYear(); if ($datey) { $years[] = $datey; } } } // Events both before and after year if (count($years) > 1 && $year >= $years[0] && $year <= $years[count($years) - 1]) { return 0; } foreach ($years as $ind => $year1) { if ($year1 - $year > $MAX_ALIVE_AGE) { return -1; } } return 0; }
/** * This function will replace a gedcom record with * the id $gid with the $gedrec * @param string $gid The XREF id of the record to replace * @param string $gedrec The new gedcom record to replace with * @param boolean $chan Whether or not to update/add the CHAN record * @param string $linkpid Tells whether or not this record change is linked with the record change of another record identified by $linkpid */ function replace_gedrec($gid, $gedrec, $chan = true, $linkpid = '') { global $fcontents, $GEDCOM, $pgv_changes, $manual_save, $pgv_private_records; $gid = strtoupper($gid); //-- restore any data that was hidden during privatizing if (isset($pgv_private_records[$gid])) { $privatedata = trim(get_last_private_data($gid)); $subs = get_all_subrecords("\n" . $privatedata, '', false, false); foreach ($subs as $s => $sub) { if (strstr($gedrec, $sub) === false) { $gedrec = trim($gedrec) . "\n" . $sub; } } unset($pgv_private_records[$gid]); } if (($gedrec = check_gedcom($gedrec, $chan)) !== false) { //-- the following block of code checks if the XREF was changed in this record. //-- if it was changed we add a warning to the change log $ct = preg_match("/0 @(.*)@/", $gedrec, $match); if ($ct > 0) { $oldgid = $gid; $gid = trim($match[1]); if ($oldgid != $gid) { if ($gid == "REF" || $gid == "new" || $gid == "NEW") { $gedrec = preg_replace("/0 @(.*)@/", "0 @" . $oldgid . "@", $gedrec); $gid = $oldgid; } else { AddToChangeLog("Warning: {$oldgid} was changed to {$gid}"); if (isset($pgv_changes[$oldgid . "_" . $GEDCOM])) { unset($pgv_changes[$oldgid . "_" . $GEDCOM]); } } } } $change = array(); $change["gid"] = $gid; $change["gedcom"] = $GEDCOM; $change["type"] = "replace"; $change["status"] = "submitted"; $change["user"] = PGV_USER_NAME; $change["time"] = time(); if (!empty($linkpid)) { $change["linkpid"] = $linkpid; } $change["undo"] = reformat_record_import($gedrec); if (!isset($pgv_changes[$gid . "_" . $GEDCOM])) { $pgv_changes[$gid . "_" . $GEDCOM] = array(); } else { $lastchange = end($pgv_changes[$gid . "_" . $GEDCOM]); if (!empty($lastchange)) { //-- append recods should continue to be marked as append if ($lastchange["type"] == "append") { $change["type"] = "append"; } else { if ($lastchange["type"] == "delete") { AddToLog("Possible GEDCOM corruption: Attempting to replace GEDCOM record {$gid} which has already been marked for deletion."); } } } } $pgv_changes[$gid . "_" . $GEDCOM][] = $change; if (PGV_USER_AUTO_ACCEPT) { accept_changes($gid . "_" . $GEDCOM); } else { write_changes(); } $backtrace = debug_backtrace(); $temp = ""; if (isset($backtrace[2])) { $temp .= basename($backtrace[2]["file"]) . " (" . $backtrace[2]["line"] . ")"; } if (isset($backtrace[1])) { $temp .= basename($backtrace[1]["file"]) . " (" . $backtrace[1]["line"] . ")"; } if (isset($backtrace[0])) { $temp .= basename($backtrace[0]["file"]) . " (" . $backtrace[0]["line"] . ")"; } $action = basename($_SERVER["SCRIPT_NAME"]); if (!empty($_REQUEST['action'])) { $action .= " " . $_REQUEST['action']; } AddToChangeLog($action . " " . $temp . " Replacing gedcom record {$gid} ->" . PGV_USER_NAME . "<-"); return true; } return false; }
/** * Merge people together. */ function _merge($record1, $record2) { // Returns second record if first is empty, no merge needed if (empty($record1)) { return $record2; } // Returns first record if second is empty, no merge needed if (empty($record2)) { return $record1; } $remoterecs = get_all_subrecords($record2, "", false, false); $localrecs = get_all_subrecords($record1, "", false, false); $newrecs = array(); //-- make sure we don't get circular links foreach ($remoterecs as $ind2 => $subrec2) { if (preg_match("/1 RFN/", $subrec2) == 0) { $newrecs[] = $subrec2; } } foreach ($localrecs as $ind => $subrec) { $found = false; if (preg_match("/1 CHAN/", $subrec) == 0) { $subrec = trim($subrec); $orig_subrec = $subrec; $subrec = preg_replace("/\\s+/", " ", $subrec); foreach ($remoterecs as $ind2 => $subrec2) { $subrec2 = trim($subrec2); $subrec2 = preg_replace("/\\s+/", " ", $subrec2); if ($subrec2 == $subrec) { $found = true; break; } } } else { $found = true; } if (!$found) { $newrecs[] = $orig_subrec; } } //-- start with the first line from the local record $pos1 = strpos($record1, "\n1"); if ($pos1 !== false) { $localrec = substr($record1, 0, $pos1 + 1); } else { $localrec = $record1; } //-- update the type of the remote record $ct = preg_match("/0 @(.*)@ (\\w*)/", $record2, $match); if ($ct > 0) { $localrec = preg_replace("/0 @(.*)@ (\\w*)/", "0 @\$1@ " . trim($match[2]), $localrec); } //-- add all of the new records foreach ($newrecs as $ind => $subrec) { $localrec .= trim($subrec) . "\n"; } $localrec = trim($localrec); //print "[<pre>$localrec</pre>]"; // Update the last change time $pos1 = strpos($localrec, "1 CHAN"); if ($pos1 !== false) { $pos2 = strpos($localrec, "\n1", $pos1 + 4); if ($pos2 === false) { $pos2 = strlen($localrec); } $newgedrec = substr($localrec, 0, $pos1); $newgedrec .= "1 CHAN\n2 DATE " . date("d M Y") . "\n"; $newgedrec .= "3 TIME " . date("H:i:s") . "\n"; $newgedrec .= "2 _PGVU @" . $this->xref . "@\n"; $newgedrec .= trim(substr($localrec, $pos2 + 1)); $localrec = $newgedrec; } else { $newgedrec = "\n1 CHAN\n2 DATE " . date("d M Y") . "\n"; $newgedrec .= "3 TIME " . date("H:i:s") . "\n"; $newgedrec .= "2 _PGVU @" . $this->xref . "@"; $localrec .= $newgedrec; } //print "merged record is ".$localrec; return $localrec; }
function get_calendar_events($jd1, $jd2, $facts = '', $ged_id = PGV_GED_ID) { global $TBLPREFIX, $gBitDb; // If no facts specified, get all except these $skipfacts = "CHAN,BAPL,SLGC,SLGS,ENDL,CENS,RESI,NOTE,ADDR,OBJE,SOUR,PAGE,DATA,TEXT"; if ($facts != '_TODO') { $skipfacts .= ',_TODO'; } $found_facts = array(); // This where clause gives events that start/end/overlap the period // e.g. 1914-1918 would show up on 1916 //$where="WHERE d_julianday1 <={$jd2} AND d_julianday2>={$jd1}"; // This where clause gives only events that start/end during the period $where = "WHERE (d_julianday1>={$jd1} AND d_julianday1<={$jd2} OR d_julianday2>={$jd1} AND d_julianday2<={$jd2})"; // Restrict to certain types of fact if (empty($facts)) { $excl_facts = "'" . preg_replace('/\\W+/', "','", $skipfacts) . "'"; $where .= " AND d_fact NOT IN ({$excl_facts})"; } else { $incl_facts = "'" . preg_replace('/\\W+/', "','", $facts) . "'"; $where .= " AND d_fact IN ({$incl_facts})"; } // Only get events from the current gedcom $where .= " AND d_file=" . $ged_id; // Now fetch these events $ind_sql = "SELECT d_gid, i_gedcom, 'INDI', d_type, d_day, d_month, d_year, d_fact, d_type FROM {$TBLPREFIX}dates, {$TBLPREFIX}individuals {$where} AND d_gid=i_id AND d_file=i_file ORDER BY d_julianday1"; $fam_sql = "SELECT d_gid, f_gedcom, 'FAM', d_type, d_day, d_month, d_year, d_fact, d_type FROM {$TBLPREFIX}dates, {$TBLPREFIX}families {$where} AND d_gid=f_id AND d_file=f_file ORDER BY d_julianday1"; foreach (array($ind_sql, $fam_sql) as $sql) { $rows = $gBitDb->getAll->fetchAll($sql); foreach ($rows as $row) { // Generate a regex to match the retrieved date - so we can find it in the original gedcom record. // TODO having to go back to the original gedcom is lame. This is why it is so slow, and needs // to be cached. We should store the level1 fact here (or somewhere) if ($row[8] == '@#DJULIAN@') { if ($row[6] < 0) { $year_regex = $row[6] . " ?[Bb]\\.? ?[Cc]\\.\\ ?"; } else { $year_regex = "({$row[6]}|" . ($row[6] - 1) . "\\/" . $row[6] % 100 . ")"; } } else { $year_regex = "0*" . $row[6]; } $ged_date_regex = "/2 DATE.*(" . ($row[4] > 0 ? "0?{$row[4]}\\s*" : "") . $row[5] . "\\s*" . ($row[6] != 0 ? $year_regex : "") . ")/i"; foreach (get_all_subrecords($row[1], $skipfacts, false, false) as $factrec) { if (preg_match("/(^1 {$row[7]}|^1 (FACT|EVEN).*\n2 TYPE {$row[7]})/s", $factrec) && preg_match($ged_date_regex, $factrec) && preg_match('/2 DATE (.+)/', $factrec, $match)) { $date = new GedcomDate($match[1]); if (preg_match('/2 PLAC (.+)/', $factrec, $match)) { $plac = $match[1]; } else { $plac = ''; } if (showFactDetails($row[7], $row[0]) && !FactViewRestricted($row[0], $factrec)) { $found_facts[] = array('id' => $row[0], 'objtype' => $row[2], 'fact' => $row[7], 'factrec' => $factrec, 'jd' => $jd1, 'anniv' => 0, 'date' => $date, 'plac' => $plac); } } } } } return $found_facts; }