individualBoxSmall($person); } else { echo Theme::theme()->individualBoxSmallEmpty(); } break; case 1: if ($person) { echo Theme::theme()->individualBox($person); } else { echo Theme::theme()->individualBoxEmpty(); } break; } } /** * print a note record * * @param string $text * @param integer $nlevel the level of the note record * @param string $nrec the note record to print * @param boolean $textOnly Don't print the "Note: " introduction * * @return string */ function print_note_record($text, $nlevel, $nrec, $textOnly = false) { global $WT_TREE; $text .= get_cont($nlevel, $nrec); // Check if shared note (we have already checked that it exists) if (preg_match('/^0 @(' . WT_REGEX_XREF . ')@ NOTE/', $nrec, $match)) { $note = WT_Note::getInstance($match[1]); $label = 'SHARED_NOTE'; // If Census assistant installed, allow it to format the note if (array_key_exists('GEDFact_assistant', WT_Module::getActiveModules())) { $html = GEDFact_assistant_WT_Module::formatCensusNote($note); } else { $html = WT_Filter::formatText($note->getNote(), $WT_TREE); } } else { $note = null; $label = 'NOTE'; $html = WT_Filter::formatText($text, $WT_TREE); } if ($textOnly) { return strip_tags($text); } if (strpos($text, "\n") === false) { // A one-line note? strip the block-level tags, so it displays inline return WT_Gedcom_Tag::getLabelValue($label, strip_tags($html, '')); } elseif ($WT_TREE->getPreference('EXPAND_NOTES')) { // A multi-line note, and we're expanding notes by default return WT_Gedcom_Tag::getLabelValue($label, $html); } else { // A multi-line note, with an expand/collapse option $element_id = Uuid::uuid4(); // NOTE: class "note-details" is (currently) used only by some third-party themes if ($note) { $first_line = '' . $note->getFullName() . ''; } else { switch ($WT_TREE->getPreference('FORMAT_TEXT')) { case 'markdown': $text = WT_Filter::markdown($text); $text = html_entity_decode(strip_tags($text, ''), ENT_QUOTES, 'UTF-8'); break; } list($text) = explode("\n", $text); $first_line = strlen($text) > 100 ? mb_substr($text, 0, 100) . WT_I18N::translate('…') : $text; } return '
' . ' ' . WT_Gedcom_Tag::getLabel($label) . ': ' . '' . $first_line . '' . '
' . ''; } } /** * Print all of the notes in this fact record * * @param string $factrec the factrecord to print the notes from * @param integer $level The level of the factrecord * @param boolean $textOnly Don't print the "Note: " introduction * * @return string HTML */ function print_fact_notes($factrec, $level, $textOnly = false) { $data = ""; $previous_spos = 0; $nlevel = $level + 1; $ct = preg_match_all("/$level NOTE (.*)/", $factrec, $match, PREG_SET_ORDER); for ($j = 0; $j < $ct; $j++) { $spos1 = strpos($factrec, $match[$j][0], $previous_spos); $spos2 = strpos($factrec . "\n$level", "\n$level", $spos1 + 1); if (!$spos2) { $spos2 = strlen($factrec); } $previous_spos = $spos2; $nrec = substr($factrec, $spos1, $spos2 - $spos1); if (!isset($match[$j][1])) { $match[$j][1] = ""; } if (!preg_match("/@(.*)@/", $match[$j][1], $nmatch)) { $data .= print_note_record($match[$j][1], $nlevel, $nrec, $textOnly); } else { $note = WT_Note::getInstance($nmatch[1]); if ($note) { if ($note->canShow()) { $noterec = $note->getGedcom(); $nt = preg_match("/0 @$nmatch[1]@ NOTE (.*)/", $noterec, $n1match); $data .= print_note_record(($nt > 0) ? $n1match[1] : "", 1, $noterec, $textOnly); if (!$textOnly) { if (strpos($noterec, "1 SOUR") !== false) { require_once WT_ROOT . 'includes/functions/functions_print_facts.php'; $data .= print_fact_sources($noterec, 1); } } } } else { $data = '
' . WT_I18N::translate('Note') . ': ' . $nmatch[1] . '
'; } } if (!$textOnly) { if (strpos($factrec, "$nlevel SOUR") !== false) { $data .= "
"; $data .= print_fact_sources($nrec, $nlevel); $data .= "
"; } } } return $data; } /** * Print a link for a popup help window. * * @param string $help_topic * @param string $module * * @return string */ function help_link($help_topic, $module = '') { return ' '; } /** * Print an external help link to the wiki site, in a new window * * @param string $topic * * @return string */ function wiki_help_link($topic) { return ' '; } /** * When a user has searched for text, highlight any matches in * the displayed string. * * @param string $string * * @return string */ function highlight_search_hits($string) { global $controller; if ($controller instanceof WT_Controller_Search && $controller->query) { // TODO: when a search contains multiple words, we search independently. // e.g. searching for "FOO BAR" will find records containing both FOO and BAR. // However, we only highlight the original search string, not the search terms. // The controller needs to provide its "query_terms" array. $regex = array(); foreach (array($controller->query) as $search_term) { $regex[] = preg_quote($search_term, '/'); } // Match these strings, provided they do not occur inside HTML tags $regex = '(' . implode('|', $regex) . ')(?![^<]*>)'; return preg_replace('/' . $regex . '/i', '$1', $string); } else { return $string; } } /** * Print the associations from the associated individuals in $event to the individuals in $record * * @param WT_Fact $event * * @return string */ function format_asso_rela_record(WT_Fact $event) { global $SEARCH_SPIDER; $parent = $event->getParent(); // To whom is this record an assocate? if ($parent instanceof WT_Individual) { // On an individual page, we just show links to the person $associates = array($parent); } elseif ($parent instanceof WT_Family) { // On a family page, we show links to both spouses $associates = $parent->getSpouses(); } else { // On other pages, it does not make sense to show associates return ''; } preg_match_all('/^1 ASSO @(' . WT_REGEX_XREF . ')@((\n[2-9].*)*)/', $event->getGedcom(), $amatches1, PREG_SET_ORDER); preg_match_all('/\n2 _?ASSO @(' . WT_REGEX_XREF . ')@((\n[3-9].*)*)/', $event->getGedcom(), $amatches2, PREG_SET_ORDER); $html = ''; // For each ASSO record foreach (array_merge($amatches1, $amatches2) as $amatch) { $person = WT_Individual::getInstance($amatch[1]); if ($person && $person->canShowName()) { // Is there a "RELA" tag if (preg_match('/\n[23] RELA (.+)/', $amatch[2], $rmatch)) { // Use the supplied relationship as a label $label = WT_Gedcom_Code_Rela::getValue($rmatch[1], $person); } else { // Use a default label $label = WT_Gedcom_Tag::getLabel('ASSO', $person); } $values = array('' . $person->getFullName() . ''); if (!$SEARCH_SPIDER) { foreach ($associates as $associate) { $relationship_name = get_associate_relationship_name($associate, $person); if (!$relationship_name) { $relationship_name = WT_Gedcom_Tag::getLabel('RELA'); } if ($parent instanceof WT_Family) { // For family ASSO records (e.g. MARR), identify the spouse with a sex icon $relationship_name .= $associate->getSexImage(); } $values[] = '' . $relationship_name . ''; } } $value = implode(' — ', $values); // Use same markup as WT_Gedcom_Tag::getLabelValue() $asso = WT_I18N::translate('%1$s: %2$s', $label, $value); } elseif (!$person && Auth::isEditor()) { $asso = WT_Gedcom_Tag::getLabelValue('ASSO', '' . $amatch[1] . ''); } else { $asso = ''; } $html .= '
' . $asso . '
'; } return $html; } /** * Format age of parents in HTML * * @param WT_Individual $person child * @param WT_Date $birth_date * * @return string HTML */ function format_parents_age(WT_Individual $person, WT_Date $birth_date) { $html = ''; $families = $person->getChildFamilies(); // Multiple sets of parents (e.g. adoption) cause complications, so ignore. if ($birth_date->isOK() && count($families) == 1) { $family = current($families); foreach ($family->getSpouses() as $parent) { if ($parent->getBirthDate()->isOK()) { $sex = $parent->getSexImage(); $age = WT_Date::getAge($parent->getBirthDate(), $birth_date, 2); $deatdate = $parent->getDeathDate(); switch ($parent->getSex()) { case 'F': // Highlight mothers who die in childbirth or shortly afterwards if ($deatdate->isOK() && $deatdate->MinJD() < $birth_date->MinJD() + 90) { $html .= ' ' . $sex . $age . ''; } else { $html .= ' ' . $sex . $age . ''; } break; case 'M': // Highlight fathers who die before the birth if ($deatdate->isOK() && $deatdate->MinJD() < $birth_date->MinJD()) { $html .= ' ' . $sex . $age . ''; } else { $html .= ' ' . $sex . $age . ''; } break; default: $html .= ' ' . $sex . $age . ''; break; } } } if ($html) { $html = '' . $html . ''; } } return $html; } /** * Print fact DATE/TIME * * @param WT_Fact $event event containing the date/age * @param WT_GedcomRecord $record the person (or couple) whose ages should be printed * @param boolean $anchor option to print a link to calendar * @param boolean $time option to print TIME value * * @return string */ function format_fact_date(WT_Fact $event, WT_GedcomRecord $record, $anchor, $time) { global $pid, $SEARCH_SPIDER, $SHOW_PARENTS_AGE; $factrec = $event->getGedcom(); $html = ''; // Recorded age if (preg_match('/\n2 AGE (.+)/', $factrec, $match)) { $fact_age = $match[1]; } else { $fact_age = ''; } if (preg_match('/\n2 HUSB\n3 AGE (.+)/', $factrec, $match)) { $husb_age = $match[1]; } else { $husb_age = ''; } if (preg_match('/\n2 WIFE\n3 AGE (.+)/', $factrec, $match)) { $wife_age = $match[1]; } else { $wife_age = ''; } // Calculated age if (preg_match('/\n2 DATE (.+)/', $factrec, $match)) { $date = new WT_Date($match[1]); $html .= ' ' . $date->display($anchor && !$SEARCH_SPIDER); // time if ($time && preg_match('/\n3 TIME (.+)/', $factrec, $match)) { $html .= ' – ' . $match[1] . ''; } $fact = $event->getTag(); if ($record instanceof WT_Individual) { if ($fact === 'BIRT' && $SHOW_PARENTS_AGE) { // age of parents at child birth $html .= format_parents_age($record, $date); } elseif ($fact !== 'CHAN' && $fact !== '_TODO') { // age at event $birth_date = $record->getBirthDate(); // Can't use getDeathDate(), as this also gives BURI/CREM events, which // wouldn't give the correct "days after death" result for people with // no DEAT. $death_event = $record->getFirstFact('DEAT'); if ($death_event) { $death_date = $death_event->getDate(); } else { $death_date = new WT_Date(''); } $ageText = ''; if ((WT_Date::Compare($date, $death_date) <= 0 || !$record->isDead()) || $fact == 'DEAT') { // Before death, print age $age = WT_Date::GetAgeGedcom($birth_date, $date); // Only show calculated age if it differs from recorded age if ($age != '') { if ( $fact_age != '' && $fact_age != $age || $fact_age == '' && $husb_age == '' && $wife_age == '' || $husb_age != '' && $record->getSex() == 'M' && $husb_age != $age || $wife_age != '' && $record->getSex() == 'F' && $wife_age != $age ) { if ($age != "0d") { $ageText = '(' . WT_I18N::translate('Age') . ' ' . get_age_at_event($age, false) . ')'; } } } } if ($fact != 'DEAT' && WT_Date::Compare($date, $death_date) >= 0) { // After death, print time since death $age = get_age_at_event(WT_Date::GetAgeGedcom($death_date, $date), true); if ($age != '') { if (WT_Date::GetAgeGedcom($death_date, $date) == "0d") { $ageText = '(' . WT_I18N::translate('on the date of death') . ')'; } else { $ageText = '(' . $age . ' ' . WT_I18N::translate('after death') . ')'; // Family events which occur after death are probably errors if ($event->getParent() instanceof WT_Family) { $ageText .= ''; } } } } if ($ageText) { $html .= ' ' . $ageText . ''; } } } elseif ($record instanceof WT_Family) { $indi = WT_Individual::getInstance($pid); if ($indi) { $birth_date = $indi->getBirthDate(); $death_date = $indi->getDeathDate(); $ageText = ''; if (WT_Date::Compare($date, $death_date) <= 0) { $age = WT_Date::GetAgeGedcom($birth_date, $date); // Only show calculated age if it differs from recorded age if ($age != '' && $age > 0) { if ( $fact_age != '' && $fact_age != $age || $fact_age == '' && $husb_age == '' && $wife_age == '' || $husb_age != '' && $indi->getSex() == 'M' && $husb_age != $age || $wife_age != '' && $indi->getSex() == 'F' && $wife_age != $age ) { $ageText = '(' . WT_I18N::translate('Age') . ' ' . get_age_at_event($age, false) . ')'; } } } if ($ageText) { $html .= ' ' . $ageText . ''; } } } } else { // 1 DEAT Y with no DATE => print YES // 1 BIRT 2 SOUR @S1@ => print YES // 1 DEAT N is not allowed // It is not proper GEDCOM form to use a N(o) value with an event tag to infer that it did not happen. $factdetail = explode(' ', trim($factrec)); if (isset($factdetail) && (count($factdetail) == 3 && strtoupper($factdetail[2]) == 'Y') || (count($factdetail) == 4 && $factdetail[2] == 'SOUR')) { $html .= WT_I18N::translate('yes'); } } // print gedcom ages foreach (array(WT_Gedcom_Tag::getLabel('AGE') => $fact_age, WT_Gedcom_Tag::getLabel('HUSB') => $husb_age, WT_Gedcom_Tag::getLabel('WIFE') => $wife_age) as $label => $age) { if ($age != '') { $html .= ' ' . $label . ': ' . get_age_at_event($age, false) . ''; } } return $html; } /** * print fact PLACe TEMPle STATus * * @param WT_Fact $event gedcom fact record * @param boolean $anchor to print a link to placelist * @param boolean $sub_records to print place subrecords * @param boolean $lds to print LDS TEMPle and STATus * * @return string HTML */ function format_fact_place(WT_Fact $event, $anchor = false, $sub_records = false, $lds = false) { global $SEARCH_SPIDER; if ($anchor) { // Show the full place name, for facts/events tab if ($SEARCH_SPIDER) { $html = $event->getPlace()->getFullName(); } else { $html = '' . $event->getPlace()->getFullName() . ''; } } else { // Abbreviate the place name, for chart boxes return ' - ' . $event->getPlace()->getShortName(); } if ($sub_records) { $placerec = get_sub_record(2, '2 PLAC', $event->getGedcom()); if (!empty($placerec)) { if (preg_match_all('/\n3 (?:_HEB|ROMN) (.+)/', $placerec, $matches)) { foreach ($matches[1] as $match) { $wt_place = new WT_Place($match, WT_GED_ID); $html .= ' - ' . $wt_place->getFullName(); } } $map_lati = ""; $cts = preg_match('/\d LATI (.*)/', $placerec, $match); if ($cts > 0) { $map_lati = $match[1]; $html .= '
' . WT_Gedcom_Tag::getLabel('LATI') . ': ' . $map_lati; } $map_long = ''; $cts = preg_match('/\d LONG (.*)/', $placerec, $match); if ($cts > 0) { $map_long = $match[1]; $html .= ' ' . WT_Gedcom_Tag::getLabel('LONG') . ': ' . $map_long; } if ($map_lati && $map_long) { $map_lati = trim(strtr($map_lati, "NSEW,�", " - -. ")); // S5,6789 ==> -5.6789 $map_long = trim(strtr($map_long, "NSEW,�", " - -. ")); // E3.456� ==> 3.456 $html .= ' '; $html .= ' '; $html .= ' '; } if (preg_match('/\d NOTE (.*)/', $placerec, $match)) { $html .= '
' . print_fact_notes($placerec, 3); } } } if ($lds) { if (preg_match('/2 TEMP (.*)/', $event->getGedcom(), $match)) { $html .= '
' . WT_I18N::translate('LDS temple') . ': ' . WT_Gedcom_Code_Temp::templeName($match[1]); } if (preg_match('/2 STAT (.*)/', $event->getGedcom(), $match)) { $html .= '
' . WT_I18N::translate('Status') . ': ' . WT_Gedcom_Code_Stat::statusName($match[1]); if (preg_match('/3 DATE (.*)/', $event->getGedcom(), $match)) { $date = new WT_Date($match[1]); $html .= ', ' . WT_Gedcom_Tag::getLabel('STAT:DATE') . ': ' . $date->display(); } } } return $html; } /** * Check for facts that may exist only once for a certain record type. * If the fact already exists in the second array, delete it from the first one. * * @param string[] $uniquefacts * @param WT_Fact[] $recfacts * @param string $type * * @return string[] */ function CheckFactUnique($uniquefacts, $recfacts, $type) { foreach ($recfacts as $factarray) { $fact = false; if (is_object($factarray)) { /* @var $factarray Event */ $fact = $factarray->getTag(); } else { if ($type === 'SOUR' || $type === 'REPO') { $factrec = $factarray[0]; } if ($type === 'FAM' || $type === 'INDI') { $factrec = $factarray[1]; } $ft = preg_match("/1 (\w+)(.*)/", $factrec, $match); if ($ft > 0) { $fact = trim($match[1]); } } if ($fact !== false) { $key = array_search($fact, $uniquefacts); if ($key !== false) { unset($uniquefacts[$key]); } } } return $uniquefacts; } /** * Print a new fact box on details pages * * @param string $id the id of the person, family, source etc the fact will be added to * @param array $usedfacts an array of facts already used in this record * @param string $type the type of record INDI, FAM, SOUR etc */ function print_add_new_fact($id, $usedfacts, $type) { global $WT_SESSION, $WT_TREE; // -- Add from clipboard if ($WT_SESSION->clipboard) { $newRow = true; foreach (array_reverse($WT_SESSION->clipboard, true) as $fact_id=>$fact) { if ($fact["type"] == $type || $fact["type"] == 'all') { if ($newRow) { $newRow = false; echo ''; echo WT_I18N::translate('Add from clipboard'), ''; echo '
'; echo ''; echo '   "; echo '
', "\n"; } } // -- Add from pick list switch ($type) { case "INDI": $addfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('INDI_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY); $uniquefacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('INDI_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY); $quickfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('INDI_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY); break; case "FAM": $addfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('FAM_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY); $uniquefacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('FAM_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY); $quickfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('FAM_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY); break; case "SOUR": $addfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('SOUR_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY); $uniquefacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('SOUR_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY); $quickfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('SOUR_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY); break; case "NOTE": $addfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('NOTE_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY); $uniquefacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('NOTE_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY); $quickfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('NOTE_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY); break; case "REPO": $addfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('REPO_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY); $uniquefacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('REPO_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY); $quickfacts = preg_split("/[, ;:]+/", $WT_TREE->getPreference('REPO_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY); break; default: return; } $addfacts = array_merge(CheckFactUnique($uniquefacts, $usedfacts, $type), $addfacts); $quickfacts = array_intersect($quickfacts, $addfacts); $translated_addfacts = array(); foreach ($addfacts as $addfact) { $translated_addfacts[$addfact] = WT_Gedcom_Tag::getLabel($addfact); } uasort($translated_addfacts, function($x, $y) { return WT_I18N::strcasecmp(WT_I18N::translate($x), WT_I18N::translate($y)); }); echo ''; echo WT_I18N::translate('Fact or event'); echo help_link('add_facts'), ''; echo ''; echo '
'; echo ''; echo ''; echo ''; foreach ($quickfacts as $fact) { echo '', WT_Gedcom_Tag::getLabel($fact), ''; } echo '
'; echo ''; } /** * javascript declaration for calendar popup */ function init_calendar_popup() { global $WEEK_START, $controller; $controller->addInlineJavascript(' cal_setMonthNames( "' . WT_I18N::translate_c('NOMINATIVE', 'January') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'February') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'March') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'April') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'May') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'June') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'July') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'August') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'September') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'October') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'November') . '", "' . WT_I18N::translate_c('NOMINATIVE', 'December') . '" ) cal_setDayHeaders( "' . WT_I18N::translate('Sun') . '", "' . WT_I18N::translate('Mon') . '", "' . WT_I18N::translate('Tue') . '", "' . WT_I18N::translate('Wed') . '", "' . WT_I18N::translate('Thu') . '", "' . WT_I18N::translate('Fri') . '", "' . WT_I18N::translate('Sat') . '" ) cal_setWeekStart(' . $WEEK_START . '); '); } /** * @param string $element_id * @param string $indiname * @param string $ged * * @return string */ function print_findindi_link($element_id, $indiname = '', $ged = WT_GEDCOM) { return ''; } /** * @param string $element_id * * @return string */ function print_findplace_link($element_id) { return ''; } /** * @param string $element_id * * @return string */ function print_findfamily_link($element_id) { return ''; } /** * @param string $element_id * * @return string */ function print_specialchar_link($element_id) { return ''; } /** * @param string $element_id * @param string[] $choices */ function print_autopaste_link($element_id, $choices) { echo ''; foreach ($choices as $choice) { echo '", $choice, ' '; } echo ''; } /** * @param string $element_id * @param string $sourcename * * @return string */ function print_findsource_link($element_id, $sourcename = '') { return ''; } /** * @param string $element_id * @param string $notename * * @return string */ function print_findnote_link($element_id, $notename = '') { return ''; } /** * @param string $element_id * * @return string */ function print_findrepository_link($element_id) { return ''; } /** * @param string $element_id * @param string $choose * * @return string */ function print_findmedia_link($element_id, $choose = '') { return ''; } /** * @param string $element_id * * @return string */ function print_findfact_link($element_id) { return ''; } /** * Summary of LDS ordinances. * * @param WT_Individual $individual * * @return string */ function get_lds_glance(WT_Individual $individual) { $BAPL = $individual->getFacts('BAPL') ? 'B' : '_'; $ENDL = $individual->getFacts('ENDL') ? 'E' : '_'; $SLGC = $individual->getFacts('SLGC') ? 'C' : '_'; $SLGS = '_'; foreach ($individual->getSpouseFamilies() as $family) { if ($family->getFacts('SLGS')) { $SLGS = ''; } } return $BAPL . $ENDL . $SLGS . $SLGC; }