if (isset($_FILES['thumbnail'])) { if (!move_uploaded_file($_FILES['thumbnail']['tmp_name'], $MEDIA_DIRECTORY . "thumbs/" . $_FILES['thumbnail']['name'])) { $error .= "\nERROR 19: " . $pgv_lang["upload_error"] . " " . file_upload_error_text($_FILES['thumbnail']['error']); } } if (!empty($error)) { addDebugLog($action . " {$error}"); print $error . "\n"; } else { addDebugLog($action . " SUCCESS"); print "SUCCESS\n"; } exit; case 'getchanges': $lastdate = new GedcomDate(safe_REQUEST($_REQUEST, 'date', '\\d\\d \\w\\w\\w \\d\\d\\d\\d')); if ($lastdate->isOK()) { if ($lastdate->MinJD() < server_jd() - 180) { addDebugLog($action . " ERROR 24: You cannot retrieve updates for more than 180 days."); print "ERROR 24: You cannot retrieve updates for more than 180 days.\n"; } else { print "SUCCESS\n"; foreach (get_recent_changes($lastdate->MinJD()) as $xref) { echo "{$xref}\n"; } } } else { addDebugLog($action . " ERROR 23: Invalid date parameter. Please use a valid date in the GEDCOM format DD MMM YYYY."); print "ERROR 23: Invalid date parameter. Please use a valid date in the GEDCOM format DD MMM YYYY.\n"; } exit; default:
/** * print parents informations * @param Family family * @param Array people * @param String family type * @return html table rows */ function printParentsRows(&$family, &$people, $type) { global $personcount, $pgv_changes, $pgv_lang, $factarray; global $PGV_IMAGE_DIR, $PGV_IMAGES; global $lang_short_cut, $LANGUAGE; $elderdate = ""; //-- new father/husband $styleadd = ""; if (isset($people["newhusb"])) { $styleadd = "red"; ?> <tr> <td class="facts_labelblue"><?php print $people["newhusb"]->getLabel(); ?> </td> <td class="<?php print $this->getPersonStyle($people["newhusb"]); ?> "> <?php print_pedigree_person($people["newhusb"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php $elderdate = $people["newhusb"]->getBirthDate(); } //-- father/husband if (isset($people["husb"])) { ?> <tr> <td class="facts_label<?php print $styleadd; ?> "><?php print $people["husb"]->getLabel(); ?> </td> <td class="<?php print $this->getPersonStyle($people["husb"]); ?> "> <?php print_pedigree_person($people["husb"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php $elderdate = $people["husb"]->getBirthDate(); } //-- missing father if ($type == "parents" && !isset($people["husb"]) && !isset($people["newhusb"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_father"]; ?> </td> <td class="facts_value"><?php print_help_link("edit_add_parent_help", "qm"); ?> <a href="javascript <?php print $pgv_lang["add_father"]; ?> " onclick="return addnewparentfamily('<?php print $this->pid; ?> ', 'HUSB', '<?php print $family->getXref(); ?> ');"><?php print $pgv_lang["add_father"]; ?> </a></td> </tr> <?php } } //-- missing husband if ($type == "spouse" && $this->indi->equals($people["wife"]) && !isset($people["husb"]) && !isset($people["newhusb"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_husb"]; ?> </td> <td class="facts_value"><a href="javascript:;" onclick="return addnewspouse('<?php print $family->getXref(); ?> ', 'HUSB');"><?php print $pgv_lang["add_husb_to_family"]; ?> </a></td> </tr> <?php } } //-- new mother/wife $styleadd = ""; if (isset($people["newwife"])) { $styleadd = "red"; ?> <tr> <td class="facts_labelblue"><?php print $people["newwife"]->getLabel($elderdate); ?> </td> <td class="<?php print $this->getPersonStyle($people["newwife"]); ?> "> <?php print_pedigree_person($people["newwife"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php } //-- mother/wife if (isset($people["wife"])) { ?> <tr> <td class="facts_label<?php print $styleadd; ?> "><?php print $people["wife"]->getLabel($elderdate); ?> </td> <td class="<?php print $this->getPersonStyle($people["wife"]); ?> "> <?php print_pedigree_person($people["wife"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php } //-- missing mother if ($type == "parents" && !isset($people["wife"]) && !isset($people["newwife"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_mother"]; ?> </td> <td class="facts_value"><?php print_help_link("edit_add_parent_help", "qm"); ?> <a href="javascript:;" onclick="return addnewparentfamily('<?php print $this->pid; ?> ', 'WIFE', '<?php print $family->getXref(); ?> ');"><?php print $pgv_lang["add_mother"]; ?> </a></td> </tr> <?php } } //-- missing wife if ($type == "spouse" && $this->indi->equals($people["husb"]) && !isset($people["wife"]) && !isset($people["newwife"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_wife"]; ?> </td> <td class="facts_value"><a href="javascript:;" onclick="return addnewspouse('<?php print $family->getXref(); ?> ', 'WIFE');"><?php print $pgv_lang["add_wife_to_family"]; ?> </a></td> </tr> <?php } } //-- marriage row if ($family->getMarriageRecord() != "" || PGV_USER_CAN_EDIT) { $styleadd = ""; $date = $family->getMarriageDate(); $place = $family->getMarriagePlace(); $famid = $family->getXref(); if (!$date && $this->show_changes && isset($pgv_changes[$famid . "_" . $GEDCOM])) { $famrec = find_updated_record($famid); $marrrec = get_sub_record(1, "1 MARR", $famrec); if ($marrrec != $family->getMarriageRecord()) { $date = new GedcomDate(get_gedcom_value("MARR:DATE", 1, $marrrec, '', false)); $place = get_gedcom_value("MARR:PLAC", 1, $marrrec, '', false); $styleadd = "blue"; } } ?> <tr> <td class="facts_label"><br /> </td> <td class="facts_value<?php print $styleadd; ?> "> <?php //echo "<span class=\"details_label\">".$factarray["NCHI"].": </span>".$family->getNumberOfChildren()."<br />"; ?> <?php if ($date && $date->isOK() || $place) { $marr_type = "MARR_" . strtoupper($family->getMarriageType()); if (isset($factarray[$marr_type])) { echo "<span class=\"details_label\">" . $factarray[$marr_type] . ": </span>"; } else { echo "<span class=\"details_label\">" . $factarray["MARR"] . ": </span>" . $family->getMarriageType(); } if ($date) { echo $date->Display(false); if (!empty($place)) { echo ' -- '; } } if (!empty($place)) { echo $place; } } else { if (get_sub_record(1, "1 _NMR", find_family_record($famid))) { // Allow special processing for different languages $func = "fact_NMR_localisation_{$lang_short_cut[$LANGUAGE]}"; if (function_exists($func)) { // Localise the _NMR facts $func("_NMR", $famid); } echo $factarray["_NMR"]; } else { if (get_sub_record(1, "1 _NMAR", find_family_record($famid))) { // Allow special processing for different languages $func = "fact_NMR_localisation_{$lang_short_cut[$LANGUAGE]}"; if (function_exists($func)) { // Localise the _NMR facts $func("_NMAR", $famid); } echo $factarray["_NMAR"]; } else { if ($family->getMarriageRecord() == "" && PGV_USER_CAN_EDIT) { print "<a href=\"#\" onclick=\"return add_new_record('" . $famid . "', 'MARR');\">" . $pgv_lang['add_marriage'] . "</a>"; } else { $factdetail = explode(' ', trim($family->getMarriageRecord())); if ($family->getMarriageType()) { $marr_type = "MARR_" . strtoupper($family->getMarriageType()); } else { $marr_type = "MARR"; } if (isset($factarray[$marr_type])) { if (isset($factdetail)) { if (count($factdetail) == 3) { if (strtoupper($factdetail[2]) == "Y") { echo "<span class=\"details_label\">" . $factarray[$marr_type] . ": </span>" . $pgv_lang["yes"]; } else { if (strtoupper($factdetail[2]) == "N") { echo "<span class=\"details_label\">" . $factarray[$marr_type] . ": </span>" . $pgv_lang["no"]; } } } } } else { echo "<span class=\"details_label\">" . $factarray["MARR"] . ": </span>" . $family->getMarriageType(); } } } } } ?> </td> </tr> <?php } }
function advancedSearch($justSql = false, $table = "individuals", $prefix = "i") { global $TBLPREFIX, $gedcom_record_cache; DMsoundex("", "opencache"); $this->myindilist = array(); $fct = count($this->fields); if ($fct == 0) { return; } $namesTable = false; $datesTable = false; $placesTable = false; $famsTable = false; $famcTable = false; $sql = ''; if ($justSql) { $sqlfields = "SELECT DISTINCT {$prefix}_id, {$prefix}_file"; } else { $sqlfields = "SELECT i_id, i_gedcom, i_isdead, i_file, i_sex"; } $sqltables = " FROM " . $TBLPREFIX . $table; $sqlwhere = " WHERE " . $prefix . "_file=" . PGV_GED_ID; $keepfields = $this->fields; for ($i = 0; $i < $fct; $i++) { $field = $this->fields[$i]; if (empty($field)) { continue; } $value = ''; if (isset($this->values[$i])) { $value = $this->values[$i]; } if (empty($value)) { continue; } $parts = preg_split("/:/", $field); //-- handle names seperately if ($parts[0] == "NAME") { // The pgv_name table contains both names and soundex values if (!$namesTable) { $sqltables .= " JOIN {$TBLPREFIX}name ON (i_file=n_file AND i_id=n_id) "; $namesTable = true; } switch (end($parts)) { case 'SDX_STD': $sdx = explode(':', soundex_std($value)); foreach ($sdx as $k => $v) { if ($parts[1] == 'GIVN') { $sdx[$k] = 'n_soundex_givn_std ' . PGV_DB::$LIKE . " '%{$v}%'"; } else { $sdx[$k] = 'n_soundex_surn_std ' . PGV_DB::$LIKE . " '%{$v}%'"; } } $sqlwhere .= ' AND (' . implode(' OR ', $sdx) . ')'; break; case 'SDX': // SDX uses DM by default. // SDX uses DM by default. case 'SDX_DM': $sdx = explode(':', soundex_dm($value)); foreach ($sdx as $k => $v) { if ($parts[1] == 'GIVN') { $sdx[$k] = 'n_soundex_givn_dm ' . PGV_DB::$LIKE . " '%{$v}%'"; } else { $sdx[$k] = 'n_soundex_surn_dm ' . PGV_DB::$LIKE . " '%{$v}%'"; } } $sqlwhere .= ' AND (' . implode(' OR ', $sdx) . ')'; break; case 'EXACT': // Exact match. switch ($parts[1]) { case 'GIVN': // Allow for exact match on multiple given names. $sqlwhere .= ' AND (n_givn ' . PGV_DB::$LIKE . " " . PGV_DB::quote($value) . " OR n_givn " . PGV_DB::$LIKE . " " . PGV_DB::quote("{$value} %") . " OR n_givn " . PGV_DB::$LIKE . " " . PGV_DB::quote("% {$value}") . " OR n_givn " . PGV_DB::$LIKE . " " . PGV_DB::quote("% {$value} %") . ")"; break; case 'SURN': $sqlwhere .= ' AND n_surname ' . PGV_DB::$LIKE . " " . PGV_DB::quote($value); break; default: $sqlwhere .= ' AND n_full ' . PGV_DB::$LIKE . " " . PGV_DB::quote($value); break; } break; case 'BEGINS': // "Begins with" match. switch ($parts[1]) { case 'GIVN': // Allow for match on start of multiple given names $sqlwhere .= ' AND (n_givn ' . PGV_DB::$LIKE . " " . PGV_DB::quote("{$value}%") . " OR n_givn " . PGV_DB::$LIKE . " " . PGV_DB::quote("% {$value}%") . ")"; break; case 'SURN': $sqlwhere .= ' AND n_surname ' . PGV_DB::$LIKE . " " . PGV_DB::quote("{$value}%"); break; default: $sqlwhere .= ' AND n_full ' . PGV_DB::$LIKE . " " . PGV_DB::quote("{$value}%"); break; } break; case 'CONTAINS': default: // Partial match. switch ($parts[1]) { case 'GIVN': $sqlwhere .= ' AND n_givn ' . PGV_DB::$LIKE . " " . PGV_DB::quote("%{$value}%"); break; case 'SURN': $sqlwhere .= ' AND n_surname ' . PGV_DB::$LIKE . " " . PGV_DB::quote("%{$value}%"); break; default: $sqlwhere .= ' AND n_full ' . PGV_DB::$LIKE . " " . PGV_DB::quote("%{$value}%"); break; } break; } } else { if (isset($parts[1]) && $parts[1] == "DATE") { if (!$datesTable) { $sqltables .= ", " . $TBLPREFIX . "dates"; $sqlwhere .= " AND " . $prefix . "_file=d_file AND " . $prefix . "_id=d_gid"; $datesTable = true; } $sqlwhere .= " AND (d_fact='" . $parts[0] . "'"; $date = new GedcomDate($value); if ($date->isOK()) { $jd1 = $date->date1->minJD; if ($date->date2) { $jd2 = $date->date2->maxJD; } else { $jd2 = $date->date1->maxJD; } if (!empty($this->plusminus[$i])) { $adjd = $this->plusminus[$i] * 365; //print $jd1.":".$jd2.":".$adjd; $jd1 = $jd1 - $adjd; $jd2 = $jd2 + $adjd; } $sqlwhere .= " AND d_julianday1>=" . $jd1 . " AND d_julianday2<=" . $jd2; } $sqlwhere .= ") "; } else { if (isset($parts[1]) && $parts[1] == "PLAC") { if (!$placesTable) { $sqltables .= ", " . $TBLPREFIX . "places, " . $TBLPREFIX . "placelinks"; $sqlwhere .= " AND " . $prefix . "_file=p_file AND p_file=pl_file AND " . $prefix . "_id=pl_gid AND pl_p_id=p_id"; $placesTable = true; } //-- soundex search //if (end($parts)=="SDX") { $places = preg_split("/[, ]+/", $value); $parr = array(); for ($j = 0; $j < count($places); $j++) { $parr[$j] = DMsoundex($places[$j]); } $sqlwhere .= " AND ("; $fnc = 0; $field = "p_dm_soundex"; foreach ($parr as $name) { foreach ($name as $name1) { if ($fnc > 0) { $sqlwhere .= " OR "; } $fnc++; $sqlwhere .= $field . " " . PGV_DB::$LIKE . " " . PGV_DB::quote("%{$name1}%"); } } $sqlwhere .= ") "; //} } else { if ($parts[0] == 'FAMS') { if (!$famsTable) { $sqltables .= ", " . $TBLPREFIX . "families as FAMS"; $sqlwhere .= " AND i_file=FAMS.f_file"; $famsTable = true; } //-- alter the fields and recurse to generate a subquery for spouse/parent fields $oldfields = $this->fields; for ($j = 0; $j < $fct; $j++) { //-- if it doesn't start with FAMS or FAMC then remove that field if (preg_match("/^" . $parts[0] . ":/", $this->fields[$j]) == 0) { $this->fields[$j] = ''; } else { $this->fields[$j] = preg_replace("/^" . $parts[0] . ":/", "", $this->fields[$j]); } } $sqlwhere .= " AND (FAMS.f_husb=i_id OR FAMS.f_wife=i_id)"; $subsql = $this->advancedSearch(true, "families", "f"); $sqlwhere .= " AND ROW(FAMS.f_id, FAMS.f_file) IN (" . $subsql . ")"; $this->fields = $oldfields; //-- remove all of the fam fields so they don't show up again for ($j = 0; $j < $fct; $j++) { //-- if it does start with FAMS or FAMC then remove that field if (preg_match("/^" . $parts[0] . ":/", $this->fields[$j]) > 0) { $this->fields[$j] = ''; } } } else { if ($parts[0] == 'FAMC') { if (!$famcTable) { $sqltables .= ", " . $TBLPREFIX . "families as FAMC"; $sqlwhere .= " AND i_file=FAMC.f_file"; $famcTable = true; } //-- alter the fields and recurse to generate a subquery for spouse/parent fields $oldfields = $this->fields; for ($j = 0; $j < $fct; $j++) { //-- if it doesn't start with FAMS or FAMC then remove that field if (preg_match("/^" . $parts[0] . ":/", $this->fields[$j]) == 0) { $this->fields[$j] = ''; } else { $this->fields[$j] = preg_replace("/^" . $parts[0] . ":/", "", $this->fields[$j]); } } $sqlwhere .= " AND (FAMC.f_chil " . PGV_DB::$LIKE . " CONCAT('%',i_id,';%'))"; $subsql = $this->advancedSearch(true, "families", "f"); $sqlwhere .= " AND ROW(FAMC.f_id, FAMC.f_file) IN (" . $subsql . ")"; $this->fields = $oldfields; //-- remove all of the fam fields so they don't show up again for ($j = 0; $j < $fct; $j++) { //-- if it does start with FAMS or FAMC then remove that field if (preg_match("/^" . $parts[0] . ":/", $this->fields[$j]) > 0) { $this->fields[$j] = ''; } } } else { if ($parts[0] == 'HUSB' || $parts[0] == 'WIFE') { if (!$famsTable) { $sqltables .= ", " . $TBLPREFIX . "individuals"; $sqlwhere .= " AND i_file=f_file"; $famsTable = true; } //-- alter the fields and recurse to generate a subquery for spouse/parent fields $oldfields = $this->fields; for ($j = 0; $j < $fct; $j++) { //-- if it doesn't start with FAMS or FAMC then remove that field if (preg_match("/^" . $parts[0] . ":/", $this->fields[$j]) == 0) { $this->fields[$j] = ''; } else { $this->fields[$j] = preg_replace("/^" . $parts[0] . ":/", "", $this->fields[$j]); } } $subsql = $this->advancedSearch(true, "individuals", "i"); if ($parts[0] == 'HUSB') { $sqlwhere .= " AND ROW(f_husb, f_file) IN (" . $subsql . ")"; } if ($parts[0] == 'WIFE') { $sqlwhere .= " AND ROW(f_wife, f_file) IN (" . $subsql . ")"; } $this->fields = $oldfields; //-- remove all of the fam fields so they don't show up again for ($j = 0; $j < $fct; $j++) { //-- if it does start with HUSB or WIFE then remove that field if (preg_match("/^" . $parts[0] . ":/", $this->fields[$j]) > 0) { $this->fields[$j] = ''; } } } else { $sqlwhere .= " AND i_gedcom " . PGV_DB::$LIKE . " "; $ct = count($parts); $liketmp = ''; for ($j = 0; $j < $ct; $j++) { $liketmp .= "%" . ($j + 1) . " " . $parts[$j] . " %"; // if ($j<$ct-1) { // $sqlwhere .= "%"; // } else { $liketmp .= "%{$value}%"; // } } $sqlwhere .= PGV_DB::quote($liketmp); } } } } } } } $sql = $sqlfields . $sqltables . $sqlwhere; // print $sql; if ($justSql) { return $sql; } $rows = PGV_DB::prepare($sql)->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) { $row['xref'] = $row['i_id']; $row['ged_id'] = $row['i_file']; $row['type'] = 'INDI'; $row['gedrec'] = $row['i_gedcom']; $object = Person::getInstance($row); $this->myindilist[$row['i_id']] = $object; } $this->fields = $keepfields; }
function compare_facts_date($arec, $brec) { if (is_array($arec)) { $arec = $arec[1]; } if (is_array($brec)) { $brec = $brec[1]; } // If either fact is undated, the facts sort equally. if (!preg_match("/2 _?DATE (.*)/", $arec, $amatch) || !preg_match("/2 _?DATE (.*)/", $brec, $bmatch)) { if (preg_match('/2 _SORT (\\d+)/', $arec, $match1) && preg_match('/2 _SORT (\\d+)/', $brec, $match2)) { return $match1[1] - $match2[1]; } return 0; } $adate = new GedcomDate($amatch[1]); $bdate = new GedcomDate($bmatch[1]); // If either date can't be parsed, don't sort. if (!$adate->isOK() || !$bdate->isOK()) { if (preg_match('/2 _SORT (\\d+)/', $arec, $match1) && preg_match('/2 _SORT (\\d+)/', $brec, $match2)) { return $match1[1] - $match2[1]; } return 0; } // Remember that dates can be ranges and overlapping ranges sort equally. $amin = $adate->MinJD(); $bmin = $bdate->MinJD(); $amax = $adate->MaxJD(); $bmax = $bdate->MaxJD(); // BEF/AFT XXX sort as the day before/after XXX if ($adate->qual1 == 'BEF') { $amin = $amin - 1; $amax = $amin; } else { if ($adate->qual1 == 'AFT') { $amax = $amax + 1; $amin = $amax; } } if ($bdate->qual1 == 'BEF') { $bmin = $bmin - 1; $bmax = $bmin; } else { if ($bdate->qual1 == 'AFT') { $bmax = $bmax + 1; $bmin = $bmax; } } if ($amax < $bmin) { return -1; } else { if ($amin > $bmax) { return 1; } else { //-- ranged date... take the type of fact sorting into account $factWeight = 0; if (preg_match('/2 _SORT (\\d+)/', $arec, $match1) && preg_match('/2 _SORT (\\d+)/', $brec, $match2)) { $factWeight = $match1[1] - $match2[1]; } //-- fact is prefered to come before, so compare using the minimum ranges if ($factWeight < 0 && $amin != $bmin) { return $amin - $bmin; } else { if ($factWeight > 0 && $bmax != $amax) { //-- fact is prefered to come after, so compare using the max of the ranges return $bmax - $amax; } else { //-- facts are the same or the ranges don't give enough info, so use the average of the range $aavg = ($amin + $amax) / 2; $bavg = ($bmin + $bmax) / 2; if ($aavg < $bavg) { return -1; } else { if ($aavg > $bavg) { return 1; } else { return $factWeight; } } } } return 0; } } }
/** * add historical events to individual facts array * * @return records added to indifacts array * * Historical facts are imported from optional language file : histo.xx.php * where xx is language code * This file should contain records similar to : * * $histo[]="1 EVEN\n2 TYPE History\n2 DATE 11 NOV 1918\n2 NOTE WW1 Armistice"; * $histo[]="1 EVEN\n2 TYPE History\n2 DATE 8 MAY 1945\n2 NOTE WW2 Armistice"; * etc... * */ function add_historical_facts() { global $LANGUAGE, $lang_short_cut; global $SHOW_RELATIVES_EVENTS; if (!$SHOW_RELATIVES_EVENTS) { return; } // Only include events between birth and death $bDate = $this->getEstimatedBirthDate(); $dDate = $this->getEstimatedDeathDate(); if (!$bDate->isOK()) { return; } if ($SHOW_RELATIVES_EVENTS && file_exists('languages/histo.' . $lang_short_cut[$LANGUAGE] . '.php')) { include 'languages/histo.' . $lang_short_cut[$LANGUAGE] . '.php'; foreach ($histo as $indexval => $hrec) { $sdate = new GedcomDate(get_gedcom_value('DATE', 2, $hrec, '', false)); if ($sdate->isOK() && GedcomDate::Compare($this->getEstimatedBirthDate(), $sdate) <= 0 && GedcomDate::Compare($sdate, $this->getEstimatedDeathDate()) <= 0) { $event = new Event($hrec); $event->setParentObject($this); $this->indifacts[] = $event; } } } }