gedcom = $gedcom;
$this->parent = $parent;
$this->fact_id = $fact_id;
$this->tag = $match[1];
} else {
// TODO need to rewrite code that passes dummy data to this function
//throw new Exception('Invalid GEDCOM data passed to WT_Fact::_construct('.$gedcom.')');
}
}
// Get the value of level 1 data in the fact
// Allow for multi-line values
function getValue() {
if (preg_match('/^1 (?:' . $this->tag . ') ?(.*(?:(?:\n2 CONT .*)*))/', $this->gedcom, $match)) {
return str_replace("\n2 CONT ", "\n", $match[1]);
} else {
return null;
}
}
// Get the record to which this fact links
function getTarget() {
$xref = trim($this->getValue(), '@');
switch ($this->tag) {
case 'FAMC':
case 'FAMS':
return WT_Family::getInstance($xref);
case 'HUSB':
case 'WIFE':
case 'CHIL':
return WT_Individual::getInstance($xref);
case 'SOUR':
return WT_Source::getInstance($xref);
case 'OBJE':
return WT_Media::getInstance($xref);
case 'REPO':
return WT_Repository::getInstance($xref);
case 'NOTE':
return WT_Note::getInstance($xref);
default:
return WT_GedcomRecord::getInstance($xref);
}
}
// Get the value of level 2 data in the fact
function getAttribute($tag) {
if (preg_match('/\n2 (?:' . $tag . ') ?(.*(?:(?:\n3 CONT .*)*)*)/', $this->gedcom, $match)) {
return str_replace("\n2 CONT ", "\n", $match[1]);
} else {
return null;
}
}
// Do the privacy rules allow us to display this fact to the current user
function canShow($access_level=WT_USER_ACCESS_LEVEL) {
// TODO - use the privacy settings for $this->gedcom_id, not the default gedcom.
global $person_facts, $global_facts;
// Does this record have an explicit RESN?
if (strpos($this->gedcom, "\n2 RESN confidential")) {
return WT_PRIV_NONE >= $access_level;
}
if (strpos($this->gedcom, "\n2 RESN privacy")) {
return WT_PRIV_USER >= $access_level;
}
if (strpos($this->gedcom, "\n2 RESN none")) {
return true;
}
// Does this record have a default RESN?
if (!$this->parent) die($eek);
$xref = $this->parent->getXref();
if (isset($person_facts[$xref][$this->tag])) {
return $person_facts[$xref][$this->tag] >= $access_level;
}
if (isset($global_facts[$this->tag])) {
return $global_facts[$this->tag] >= $access_level;
}
// No restrictions - it must be public
return true;
}
// Check whether this fact is protected against edit
public function canEdit() {
// Managers can edit anything
// Members cannot edit RESN, CHAN and locked records
return
$this->parent->canEdit() && !$this->isOld() && (
WT_USER_GEDCOM_ADMIN ||
WT_USER_CAN_EDIT && strpos($this->gedcom, "\n2 RESN locked")===false && $this->getTag()!='RESN' && $this->getTag()!='CHAN'
);
}
// The place where the event occured.
function getPlace() {
if ($this->place === null) {
$this->place = $this->getAttribute('PLAC');
}
return $this->place;
}
// We can call this function many times, especially when sorting,
// so keep a copy of the date.
function getDate() {
if ($this->date === null) {
$this->date = new WT_Date($this->getAttribute('DATE'));
}
return $this->date;
}
// The raw GEDCOM data for this fact
function getGedcom() {
return $this->gedcom;
}
// Unique identifier for the fact
function getFactId() {
return $this->fact_id;
}
// What sort of fact is this?
function getTag() {
return $this->tag;
}
// Used to convert a real fact (e.g. BIRT) into a close-relative’s fact (e.g. _BIRT_CHIL)
function setTag($tag) {
$this->tag = $tag;
}
// The Person/Family record where this WT_Fact came from
function getParent() {
return $this->parent;
}
function getLabel($abbreviate=false) {
if ($abbreviate) {
return WT_Gedcom_Tag::getAbbreviation($this->tag);
} else {
switch($this->tag) {
case 'EVEN':
case 'FACT':
if ($this->getType()) {
// Custom FACT/EVEN - with a TYPE
return WT_I18N::translate(htmlspecialchars($this->type));
}
// no break - drop into next case
default:
return WT_Gedcom_Tag::getLabel($this->tag, $this->parent);
}
}
}
// Is this a pending edit?
public function setIsOld() {
$this->is_old = true;
$this->is_new = false;
}
public function isOld() {
return $this->is_old;
}
public function setIsNew() {
$this->is_new = true;
$this->is_old = false;
}
public function isNew() {
return $this->is_new;
}
// Print a simple fact version of this event
function print_simple_fact($return=false, $anchor=false) {
global $ABBREVIATE_CHART_LABELS;
$value = $this->getValue();
$data = ''.$this->getLabel($ABBREVIATE_CHART_LABELS).'';
// Don't display "yes", because format_fact_date() does this for us. (Should it?)
if ($value && $value != 'Y') {
$data .= ' ' . htmlspecialchars($value) . '';
}
$data .= ' '.format_fact_date($this, $this->getParent(), $anchor, false);
$data .= ' '.format_fact_place($this, $anchor, false, false);
$data .= '
';
if ($return) {
return $data;
} else {
echo $data;
}
}
// Display an icon for this fact.
// Icons are held in a theme subfolder. Not all themes provide icons.
function Icon() {
$dir=WT_THEME_DIR.'images/facts/';
$tag=$this->getTag();
$file=$tag.'.png';
if (file_exists($dir.$file)) {
return '
';
} elseif (file_exists($dir.'NULL.png')) {
// Spacer image - for alignment - until we move to a sprite.
return '
';
} else {
return '';
}
}
// Static Helper functions to sort events
static function CompareDate($a, $b) {
if ($a->getDate()->isOK() && $b->getDate()->isOK()) {
// If both events have dates, compare by date
$ret=WT_Date::Compare($a->getDate(), $b->getDate());
if ($ret==0) {
// If dates are the same, compare by fact type
$ret=self::CompareType($a, $b);
// If the fact type is also the same, retain the initial order
if ($ret==0) {
$ret=$a->sortOrder - $b->sortOrder;
}
}
return $ret;
} else {
// One or both events have no date - retain the initial orde
return $a->sortOrder - $b->sortOrder;
}
}
// Static method to Compare two events by their type
static function CompareType($a, $b) {
global $factsort;
if (empty($factsort))
$factsort=array_flip(array(
"BIRT",
"_HNM",
"ALIA", "_AKA", "_AKAN",
"ADOP", "_ADPF", "_ADPF",
"_BRTM",
"CHR", "BAPM",
"FCOM",
"CONF",
"BARM", "BASM",
"EDUC",
"GRAD",
"_DEG",
"EMIG", "IMMI",
"NATU",
"_MILI", "_MILT",
"ENGA",
"MARB", "MARC", "MARL", "_MARI", "_MBON",
"MARR", "MARR_CIVIL", "MARR_RELIGIOUS", "MARR_PARTNERS", "MARR_UNKNOWN", "_COML",
"_STAT",
"_SEPR",
"DIVF",
"MARS",
"_BIRT_CHIL",
"DIV", "ANUL",
"_BIRT_", "_MARR_", "_DEAT_","_BURI_", // other events of close relatives
"CENS",
"OCCU",
"RESI",
"PROP",
"CHRA",
"RETI",
"FACT", "EVEN",
"_NMR", "_NMAR", "NMR",
"NCHI",
"WILL",
"_HOL",
"_????_",
"DEAT",
"_FNRL", "BURI", "CREM", "_INTE",
"_YART",
"_NLIV",
"PROB",
"TITL",
"COMM",
"NATI",
"CITN",
"CAST",
"RELI",
"SSN", "IDNO",
"TEMP",
"SLGC", "BAPL", "CONL", "ENDL", "SLGS",
"ADDR", "PHON", "EMAIL", "_EMAIL", "EMAL", "FAX", "WWW", "URL", "_URL",
"AFN", "REFN", "_PRMN", "REF", "RIN", "_UID",
"CHAN", "_TODO",
"NOTE", "SOUR", "OBJE"
));
// Facts from same families stay grouped together
// Keep MARR and DIV from the same families from mixing with events from other FAMs
// Use the original order in which the facts were added
if ($a->parent instanceof WT_Family && $b->parent instanceof WT_Family && !$a->parent->equals($b->parent)) {
return $a->sortOrder - $b->sortOrder;
}
$atag = $a->getTag();
$btag = $b->getTag();
// Events not in the above list get mapped onto one that is.
if (!array_key_exists($atag, $factsort)) {
if (preg_match('/^(_(BIRT|MARR|DEAT|BURI)_)/', $atag, $match)) {
$atag=$match[1];
} else {
$atag="_????_";
}
}
if (!array_key_exists($btag, $factsort)) {
if (preg_match('/^(_(BIRT|MARR|DEAT|BURI)_)/', $btag, $match)) {
$btag=$match[1];
} else {
$btag="_????_";
}
}
//-- don't let dated after DEAT/BURI facts sort non-dated facts before DEAT/BURI
//-- treat dated after BURI facts as BURI instead
if ($a->getAttribute('DATE')!=NULL && $factsort[$atag]>$factsort['BURI'] && $factsort[$atag]<$factsort['CHAN']) $atag='BURI';
if ($b->getAttribute('DATE')!=NULL && $factsort[$btag]>$factsort['BURI'] && $factsort[$btag]<$factsort['CHAN']) $btag='BURI';
$ret = $factsort[$atag]-$factsort[$btag];
//-- if facts are the same then put dated facts before non-dated facts
if ($ret==0) {
if ($a->getAttribute('DATE')!=NULL && $b->getAttribute('DATE')==NULL) return -1;
if ($b->getAttribute('DATE')!=NULL && $a->getAttribute('DATE')==NULL) return 1;
//-- if no sorting preference, then keep original ordering
$ret = $a->sortOrder - $b->sortOrder;
}
return $ret;
}
}