Exemple #1
0
     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;
 }
Exemple #4
0
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;
             }
         }
     }
 }