/** * get edit menu */ public function getEditMenu() { if (!$this->record || $this->record->isPendingDeletion()) { return null; } // edit menu $menu = new Menu(I18N::translate('Edit'), '#', 'menu-record'); // edit raw if (Auth::isAdmin() || Auth::isEditor($this->record->getTree()) && $this->record->getTree()->getPreference('SHOW_GEDCOM_RECORD')) { $menu->addSubmenu(new Menu(I18N::translate('Edit raw GEDCOM'), '#', 'menu-record-editraw', array('onclick' => 'return edit_raw("' . $this->record->getXref() . '");'))); } // delete if (Auth::isEditor($this->record->getTree())) { $menu->addSubmenu(new Menu(I18N::translate('Delete'), '#', 'menu-record-del', array('onclick' => 'return delete_record("' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs(Filter::unescapeHtml($this->record->getFullName()))) . '", "' . $this->record->getXref() . '");'))); } // add to favorites if (Module::getModuleByName('user_favorites')) { $menu->addSubmenu(new Menu(I18N::translate('Add to favorites'), '#', 'menu-record-addfav', array('onclick' => 'jQuery.post("module.php?mod=user_favorites&mod_action=menu-add-favorite" ,{xref:"' . $this->record->getXref() . '"},function(){location.reload();})'))); } // Get the link for the first submenu and set it as the link for the main menu if ($menu->getSubmenus()) { $submenus = $menu->getSubmenus(); $menu->setLink($submenus[0]->getLink()); $menu->setAttrs($submenus[0]->getAttrs()); } return $menu; }
/** * Startup activity */ public function __construct() { // Automatically fix broken links if ($this->record && $this->record->canEdit()) { $broken_links = 0; foreach ($this->record->getFacts('HUSB|WIFE|CHIL|FAMS|FAMC|REPO') as $fact) { if (!$fact->isPendingDeletion() && $fact->getTarget() === null) { $this->record->deleteFact($fact->getFactId(), false); FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been deleted.', $this->record->getFullName(), $fact->getValue())); $broken_links = true; } } foreach ($this->record->getFacts('NOTE|SOUR|OBJE') as $fact) { // These can be links or inline. Only delete links. if (!$fact->isPendingDeletion() && $fact->getTarget() === null && preg_match('/^@.*@$/', $fact->getValue())) { $this->record->deleteFact($fact->getFactId(), false); FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been deleted.', $this->record->getFullName(), $fact->getValue())); $broken_links = true; } } if ($broken_links) { // Reload the updated family $this->record = GedcomRecord::getInstance($this->record->getXref(), $this->record->getTree()); } } parent::__construct(); // We want robots to index this page $this->setMetaRobots('index,follow'); // Set a page title if ($this->record) { if ($this->record->canShowName()) { // e.g. "John Doe" or "1881 Census of Wales" $this->setPageTitle($this->record->getFullName()); } else { // e.g. "Individual" or "Source" $record = $this->record; $this->setPageTitle(GedcomTag::getLabel($record::RECORD_TYPE)); } } else { // No such record $this->setPageTitle(I18N::translate('Private')); } }
/** * get edit menu */ public function getEditMenu() { if (!$this->record || $this->record->isPendingDeletion()) { return null; } // edit menu $menu = new Menu(I18N::translate('Edit'), '#', 'menu-record'); // edit raw if (Auth::isAdmin() || Auth::isEditor($this->record->getTree()) && $this->record->getTree()->getPreference('SHOW_GEDCOM_RECORD')) { $menu->addSubmenu(new Menu(I18N::translate('Edit the raw GEDCOM'), '#', 'menu-record-editraw', array('onclick' => 'return edit_raw("' . $this->record->getXref() . '");'))); } // delete if (Auth::isEditor($this->record->getTree())) { $menu->addSubmenu(new Menu(I18N::translate('Delete'), '#', 'menu-record-del', array('onclick' => 'return delete_record("' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs(Filter::unescapeHtml($this->record->getFullName()))) . '", "' . $this->record->getXref() . '");'))); } return $menu; }
/** * Print a form to add an individual or edit an individual’s name * * @param string $nextaction * @param Individual $person * @param Family $family * @param Fact $name_fact * @param string $famtag * @param string $gender */ function print_indi_form($nextaction, Individual $person = null, Family $family = null, Fact $name_fact = null, $famtag = 'CHIL', $gender = 'U') { global $WT_TREE, $bdm, $controller; if ($person) { $xref = $person->getXref(); } elseif ($family) { $xref = $family->getXref(); } else { $xref = 'new'; } // Different cultures do surnames differently $surname_tradition = SurnameTradition::create($WT_TREE->getPreference('SURNAME_TRADITION')); $name_fields = array(); if ($name_fact) { // Editing an existing name $name_fact_id = $name_fact->getFactId(); $name_type = $name_fact->getAttribute('TYPE'); $namerec = $name_fact->getGedcom(); foreach (Config::standardNameFacts() as $tag) { if ($tag === 'NAME') { $name_fields[$tag] = $name_fact->getValue(); } else { $name_fields[$tag] = $name_fact->getAttribute($tag); } } // Populate any missing 2 XXXX fields from the 1 NAME field $npfx_accept = implode('|', Config::namePrefixes()); if (preg_match('/(((' . $npfx_accept . ')\\.? +)*)([^\\n\\/"]*)("(.*)")? *\\/(([a-z]{2,3} +)*)(.*)\\/ *(.*)/i', $name_fields['NAME'], $name_bits)) { if (empty($name_fields['NPFX'])) { $name_fields['NPFX'] = $name_bits[1]; } if (empty($name_fields['SPFX']) && empty($name_fields['SURN'])) { $name_fields['SPFX'] = trim($name_bits[7]); // For names with two surnames, there will be four slashes. // Turn them into a list $name_fields['SURN'] = preg_replace('~/[^/]*/~', ',', $name_bits[9]); } if (empty($name_fields['GIVN'])) { $name_fields['GIVN'] = $name_bits[4]; } if (empty($name_fields['NICK']) && !empty($name_bits[6]) && !preg_match('/^2 NICK/m', $namerec)) { $name_fields['NICK'] = $name_bits[6]; } } } else { // Creating a new name $name_fact_id = null; $name_type = null; $namerec = null; // Populate the standard NAME field and subfields foreach (Config::standardNameFacts() as $tag) { $name_fields[$tag] = ''; } // Inherit surname from parents, spouse or child if ($family) { $father = $family->getHusband(); if ($father && $father->getFirstFact('NAME')) { $father_name = $father->getFirstFact('NAME')->getValue(); } else { $father_name = ''; } $mother = $family->getWife(); if ($mother && $mother->getFirstFact('NAME')) { $mother_name = $mother->getFirstFact('NAME')->getValue(); } else { $mother_name = ''; } } else { $father = null; $mother = null; $father_name = ''; $mother_name = ''; } if ($person && $person->getFirstFact('NAME')) { $indi_name = $person->getFirstFact('NAME')->getValue(); } else { $indi_name = ''; } switch ($nextaction) { case 'add_child_to_family_action': $name_fields = $surname_tradition->newChildNames($father_name, $mother_name, $gender) + $name_fields; break; case 'add_child_to_individual_action': if ($person->getSex() === 'F') { $name_fields = $surname_tradition->newChildNames('', $indi_name, $gender) + $name_fields; } else { $name_fields = $surname_tradition->newChildNames($indi_name, '', $gender) + $name_fields; } break; case 'add_parent_to_individual_action': $name_fields = $surname_tradition->newParentNames($indi_name, $gender) + $name_fields; break; case 'add_spouse_to_family_action': if ($father) { $name_fields = $surname_tradition->newSpouseNames($father_name, $gender) + $name_fields; } else { $name_fields = $surname_tradition->newSpouseNames($mother_name, $gender) + $name_fields; } break; case 'add_spouse_to_individual_action': $name_fields = $surname_tradition->newSpouseNames($indi_name, $gender) + $name_fields; break; case 'add_unlinked_indi_action': case 'update': if ($surname_tradition->hasSurnames()) { $name_fields['NAME'] = '//'; } break; } } $bdm = ''; // used to copy '1 SOUR' to '2 SOUR' for BIRT DEAT MARR echo '<div id="edit_interface-page">'; echo '<h4>', $controller->getPageTitle(), '</h4>'; FunctionsPrint::initializeCalendarPopup(); echo '<form method="post" name="addchildform" onsubmit="return checkform();">'; echo '<input type="hidden" name="ged" value="', $WT_TREE->getNameHtml(), '">'; echo '<input type="hidden" name="action" value="', $nextaction, '">'; echo '<input type="hidden" name="fact_id" value="', $name_fact_id, '">'; echo '<input type="hidden" name="xref" value="', $xref, '">'; echo '<input type="hidden" name="famtag" value="', $famtag, '">'; echo '<input type="hidden" name="gender" value="', $gender, '">'; echo '<input type="hidden" name="goto" value="">'; // set by javascript echo Filter::getCsrf(); echo '<table class="facts_table">'; switch ($nextaction) { case 'add_child_to_family_action': case 'add_child_to_individual_action': // When adding a new child, specify the pedigree FunctionsEdit::addSimpleTag('0 PEDI'); break; case 'update': // When adding/editing a name, specify the type FunctionsEdit::addSimpleTag('0 TYPE ' . $name_type, '', '', null, $person); break; } // First - new/existing standard name fields foreach ($name_fields as $tag => $value) { if (substr_compare($tag, '_', 0, 1) !== 0) { FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value); } } // Second - new/existing advanced name fields if ($surname_tradition->hasMarriedNames() || preg_match('/\\n2 _MARNM /', $namerec)) { $adv_name_fields = array('_MARNM' => ''); } else { $adv_name_fields = array(); } if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('ADVANCED_NAME_FACTS'), $match)) { foreach ($match[1] as $tag) { $adv_name_fields[$tag] = ''; } } foreach (array_keys($adv_name_fields) as $tag) { // Edit existing tags, grouped together if (preg_match_all('/2 ' . $tag . ' (.+)/', $namerec, $match)) { foreach ($match[1] as $value) { FunctionsEdit::addSimpleTag('2 ' . $tag . ' ' . $value, '', GedcomTag::getLabel('NAME:' . $tag, $person)); if ($tag === '_MARNM') { preg_match_all('/\\/([^\\/]*)\\//', $value, $matches); FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1])); } } } // Allow a new tag to be entered if (!array_key_exists($tag, $name_fields)) { FunctionsEdit::addSimpleTag('0 ' . $tag, '', GedcomTag::getLabel('NAME:' . $tag, $person)); if ($tag === '_MARNM') { FunctionsEdit::addSimpleTag('0 _MARNM_SURN'); } } } // Third - new/existing custom name fields foreach ($name_fields as $tag => $value) { if (substr_compare($tag, '_', 0, 1) === 0) { FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value); if ($tag === '_MARNM') { preg_match_all('/\\/([^\\/]*)\\//', $value, $matches); FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1])); } } } // Fourth - SOUR, NOTE, _CUSTOM, etc. if ($namerec) { $gedlines = explode("\n", $namerec); // -- find the number of lines in the record $fields = explode(' ', $gedlines[0]); $glevel = $fields[0]; $level = $glevel; $type = trim($fields[1]); $tags = array(); $i = 0; do { if ($type !== 'TYPE' && !array_key_exists($type, $name_fields) && !array_key_exists($type, $adv_name_fields)) { $text = ''; for ($j = 2; $j < count($fields); $j++) { if ($j > 2) { $text .= ' '; } $text .= $fields[$j]; } while ($i + 1 < count($gedlines) && preg_match('/' . ($level + 1) . ' CONT ?(.*)/', $gedlines[$i + 1], $cmatch) > 0) { $text .= "\n" . $cmatch[2]; $i++; } FunctionsEdit::addSimpleTag($level . ' ' . $type . ' ' . $text); } $tags[] = $type; $i++; if (isset($gedlines[$i])) { $fields = explode(' ', $gedlines[$i]); $level = $fields[0]; if (isset($fields[1])) { $type = $fields[1]; } } } while ($level > $glevel && $i < count($gedlines)); } // If we are adding a new individual, add the basic details if ($nextaction !== 'update') { echo '</table><br><table class="facts_table">'; // 1 SEX if ($famtag === 'HUSB' || $gender === 'M') { FunctionsEdit::addSimpleTag("0 SEX M"); } elseif ($famtag === 'WIFE' || $gender === 'F') { FunctionsEdit::addSimpleTag('0 SEX F'); } else { FunctionsEdit::addSimpleTag('0 SEX'); } $bdm = 'BD'; if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { foreach ($matches[1] as $match) { if (!in_array($match, explode('|', WT_EVENTS_DEAT))) { FunctionsEdit::addSimpleTags($match); } } } //-- if adding a spouse add the option to add a marriage fact to the new family if ($nextaction === 'add_spouse_to_individual_action' || $nextaction === 'add_spouse_to_family_action') { $bdm .= 'M'; if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) { foreach ($matches[1] as $match) { FunctionsEdit::addSimpleTags($match); } } } if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { foreach ($matches[1] as $match) { if (in_array($match, explode('|', WT_EVENTS_DEAT))) { FunctionsEdit::addSimpleTags($match); } } } } echo keep_chan($person); echo '</table>'; if ($nextaction === 'update') { // GEDCOM 5.5.1 spec says NAME doesn’t get a OBJE FunctionsEdit::printAddLayer('SOUR'); FunctionsEdit::printAddLayer('NOTE'); FunctionsEdit::printAddLayer('SHARED_NOTE'); FunctionsEdit::printAddLayer('RESN'); } else { FunctionsEdit::printAddLayer('SOUR', 1); FunctionsEdit::printAddLayer('NOTE', 1); FunctionsEdit::printAddLayer('SHARED_NOTE', 1); FunctionsEdit::printAddLayer('RESN', 1); } // If we are editing an existing name, allow raw GEDCOM editing if ($name_fact && (Auth::isAdmin() || $WT_TREE->getPreference('SHOW_GEDCOM_RECORD'))) { echo '<br><br><a href="edit_interface.php?action=editrawfact&xref=', $xref, '&fact_id=', $name_fact->getFactId(), '&ged=', $WT_TREE->getNameUrl(), '">', I18N::translate('Edit raw GEDCOM'), '</a>'; } echo '<p id="save-cancel">'; echo '<input type="submit" class="save" value="', I18N::translate('save'), '">'; if (preg_match('/^add_(child|spouse|parent|unlinked_indi)/', $nextaction)) { echo '<input type="submit" class="save" value="', I18N::translate('go to new individual'), '" onclick="document.addchildform.goto.value=\'new\';">'; } echo '<input type="button" class="cancel" value="', I18N::translate('close'), '" onclick="window.close();">'; echo '</p>'; echo '</form>'; $controller->addInlineJavascript(' SURNAME_TRADITION="' . $WT_TREE->getPreference('SURNAME_TRADITION') . '"; gender="' . $gender . '"; famtag="' . $famtag . '"; function trim(str) { str=str.replace(/\\s\\s+/g, " "); return str.replace(/(^\\s+)|(\\s+$)/g, ""); } function lang_class(str) { if (str.match(/[\\u0370-\\u03FF]/)) return "greek"; if (str.match(/[\\u0400-\\u04FF]/)) return "cyrillic"; if (str.match(/[\\u0590-\\u05FF]/)) return "hebrew"; if (str.match(/[\\u0600-\\u06FF]/)) return "arabic"; return "latin"; // No matched text implies latin :-) } // Generate a full name from the name components function generate_name() { var npfx = jQuery("#NPFX").val(); var givn = jQuery("#GIVN").val(); var spfx = jQuery("#SPFX").val(); var surn = jQuery("#SURN").val(); var nsfx = jQuery("#NSFX").val(); if (SURNAME_TRADITION === "polish" && (gender === "F" || famtag === "WIFE")) { surn = surn.replace(/ski$/, "ska"); surn = surn.replace(/cki$/, "cka"); surn = surn.replace(/dzki$/, "dzka"); surn = surn.replace(/żki$/, "żka"); } // Commas are used in the GIVN and SURN field to separate lists of surnames. // For example, to differentiate the two Spanish surnames from an English // double-barred name. // Commas *may* be used in other fields, and will form part of the NAME. if (WT_LOCALE=="vi" || WT_LOCALE=="hu") { // Default format: /SURN/ GIVN return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+givn.replace(/ *, */g, " ")+" "+nsfx); } else if (WT_LOCALE=="zh") { // Default format: /SURN/GIVN return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/"+givn.replace(/ *, */g, " ")+" "+nsfx); } else { // Default format: GIVN /SURN/ return trim(npfx+" "+givn.replace(/ *, */g, " ")+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+nsfx); } } // Update the NAME and _MARNM fields from the name components // and also display the value in read-only "gedcom" format. function updatewholename() { // Don’t update the name if the user manually changed it if (manualChange) { return; } var npfx = jQuery("#NPFX").val(); var givn = jQuery("#GIVN").val(); var spfx = jQuery("#SPFX").val(); var surn = jQuery("#SURN").val(); var nsfx = jQuery("#NSFX").val(); var name = generate_name(); jQuery("#NAME").val(name); jQuery("#NAME_display").text(name); // Married names inherit some NSFX values, but not these nsfx = nsfx.replace(/^(I|II|III|IV|V|VI|Junior|Jr\\.?|Senior|Sr\\.?)$/i, ""); // Update _MARNM field from _MARNM_SURN field and display it // Be careful of mixing latin/hebrew/etc. character sets. var ip = document.getElementsByTagName("input"); var marnm_id = ""; var romn = ""; var heb = ""; for (var i = 0; i < ip.length; i++) { var val = trim(ip[i].value); if (ip[i].id.indexOf("_HEB") === 0) heb = val; if (ip[i].id.indexOf("ROMN") === 0) romn = val; if (ip[i].id.indexOf("_MARNM") === 0) { if (ip[i].id.indexOf("_MARNM_SURN") === 0) { var msurn = ""; if (val !== "") { var lc = lang_class(document.getElementById(ip[i].id).value); if (lang_class(name) === lc) msurn = trim(npfx + " " + givn + " /" + val + "/ " + nsfx); else if (lc === "hebrew") msurn = heb.replace(/\\/.*\\//, "/" + val + "/"); else if (lang_class(romn) === lc) msurn = romn.replace(/\\/.*\\//, "/" + val + "/"); } document.getElementById(marnm_id).value = msurn; document.getElementById(marnm_id+"_display").innerHTML = msurn; } else { marnm_id = ip[i].id; } } } } // Toggle the name editor fields between // <input type="hidden"> <span style="display:inline"> // <input type="text"> <span style="display:hidden"> var oldName = ""; // Calls to generate_name() trigger an update - hence need to // set the manual change to true first. We are probably // listening to the wrong events on the input fields... var manualChange = true; manualChange = generate_name() !== jQuery("#NAME").val(); function convertHidden(eid) { var input1 = jQuery("#" + eid); var input2 = jQuery("#" + eid + "_display"); // Note that IE does not allow us to change the type of an input, so we must create a new one. if (input1.attr("type")=="hidden") { input1.replaceWith(input1.clone().attr("type", "text")); input2.hide(); } else { input1.replaceWith(input1.clone().attr("type", "hidden")); input2.show(); } } /** * if the user manually changed the NAME field, then update the textual * HTML representation of it * If the value changed set manualChange to true so that changing * the other fields doesn’t change the NAME line */ function updateTextName(eid) { var element = document.getElementById(eid); if (element) { if (element.value!=oldName) manualChange = true; var delement = document.getElementById(eid+"_display"); if (delement) { delement.innerHTML = element.value; } } } function checkform() { var ip=document.getElementsByTagName("input"); for (var i=0; i<ip.length; i++) { // ADD slashes to _HEB and _AKA names if (ip[i].id.indexOf("_AKA")==0 || ip[i].id.indexOf("_HEB")==0 || ip[i].id.indexOf("ROMN")==0) if (ip[i].value.indexOf("/")<0 && ip[i].value!="") ip[i].value=ip[i].value.replace(/([^\\s]+)\\s*$/, "/$1/"); // Blank out temporary _MARNM_SURN if (ip[i].id.indexOf("_MARNM_SURN")==0) ip[i].value=""; // Convert "xxx yyy" and "xxx y yyy" surnames to "xxx,yyy" if ((SURNAME_TRADITION=="spanish" || "SURNAME_TRADITION"=="portuguese") && ip[i].id.indexOf("SURN")==0) { ip[i].value=document.forms[0].SURN.value.replace(/^\\s*([^\\s,]{2,})\\s+([iIyY] +)?([^\\s,]{2,})\\s*$/, "$1,$3"); } } return true; } // If the name isn’t initially formed from the components in a standard way, // then don’t automatically update it. if (document.getElementById("NAME").value!=generate_name() && document.getElementById("NAME").value!="//") { convertHidden("NAME"); } '); echo '</div>'; }
/** * A label for a parental family group * * @param Family $family * * @return string */ public function getChildFamilyLabel(Family $family) { if (preg_match('/\\n1 FAMC @' . $family->getXref() . '@(?:\\n[2-9].*)*\\n2 PEDI (.+)/', $this->getGedcom(), $match)) { // A specified pedigree return GedcomCodePedi::getChildFamilyLabel($match[1]); } else { // Default (birth) pedigree return GedcomCodePedi::getChildFamilyLabel(''); } }
/** * print the children table for a family * * @param Family $family family * @param string $childid child ID * @param int $sosa child sosa number * @param string $label indi label (descendancy booklet) * @param int $show_cousins display cousins on chart * @param int $show_full large or small box */ public static function printFamilyChildren(Family $family, $childid = '', $sosa = 0, $label = '', $show_cousins = 0, $show_full = 1) { if ($show_full) { $bheight = Theme::theme()->parameter('chart-box-y'); } else { $bheight = Theme::theme()->parameter('compact-chart-box-y'); } $pbheight = $bheight + 14; $children = $family->getChildren(); $numchil = count($children); echo '<table border="0" cellpadding="0" cellspacing="2"><tr>'; if ($sosa > 0) { echo '<td></td>'; } echo '<td><span class="subheaders">'; if ($numchil == 0) { echo I18N::translate('No children'); } else { echo I18N::plural('%s child', '%s children', $numchil, $numchil); } echo '</span>'; if ($sosa == 0 && Auth::isEditor($family->getTree())) { echo '<br>'; echo "<a href=\"#\" onclick=\"return add_child_to_family('", $family->getXref(), "', 'U');\">" . I18N::translate('Add a child to this family') . "</a>"; echo ' <a class="icon-sex_m_15x15" href="#" onclick="return add_child_to_family(\'', $family->getXref(), '\', \'M\');" title="', I18N::translate('son'), '"></a>'; echo ' <a class="icon-sex_f_15x15" href="#" onclick="return add_child_to_family(\'', $family->getXref(), '\', \'F\');" title="', I18N::translate('daughter'), '"></a>'; echo '<br><br>'; } echo '</td>'; if ($sosa > 0) { echo '<td></td><td></td>'; } echo '</tr>'; $nchi = 1; if ($children) { foreach ($children as $child) { echo '<tr>'; if ($sosa != 0) { if ($child->getXref() == $childid) { self::printSosaNumber($sosa, $childid); } elseif (empty($label)) { self::printSosaNumber(""); } else { self::printSosaNumber($label . $nchi++ . "."); } } if ($child->isPendingAddtion()) { echo '<td valign="middle" class="new">'; } elseif ($child->isPendingDeletion()) { echo '<td valign="middle" class="old">'; } else { echo '<td valign="middle">'; } FunctionsPrint::printPedigreePerson($child, $show_full); echo "</td>"; if ($sosa != 0) { // loop for all families where current child is a spouse $famids = $child->getSpouseFamilies(); $maxfam = count($famids) - 1; for ($f = 0; $f <= $maxfam; $f++) { $famid_child = $famids[$f]->getXref(); // multiple marriages if ($f > 0) { echo '</tr><tr><td></td>'; echo '<td valign="top"'; if (I18N::direction() === 'rtl') { echo ' align="left">'; } else { echo ' align="right">'; } //find out how many cousins there are to establish vertical line on second families $fchildren = $famids[$f]->getChildren(); $kids = count($fchildren); $Pheader = ($bheight - 1) * $kids; $PBadj = 6; // default if ($show_cousins > 0) { if ($kids) { $PBadj = max(0, $Pheader / 2 + $kids * 4.5); } } if ($f == $maxfam) { echo "<img height=\"" . ($bheight / 2 + $PBadj) . "px\""; } else { echo "<img height=\"" . $pbheight . "px\""; } echo " width=\"3\" src=\"" . Theme::theme()->parameter('image-vline') . "\" alt=\"\">"; echo "</td>"; } echo "<td class=\"details1\" valign=\"middle\" align=\"center\">"; $spouse = $famids[$f]->getSpouse($child); $marr = $famids[$f]->getFirstFact('MARR'); $div = $famids[$f]->getFirstFact('DIV'); if ($marr) { // marriage date echo $marr->getDate()->minimumDate()->format('%Y'); // divorce date if ($div) { echo '–', $div->getDate()->minimumDate()->format('%Y'); } } echo "<br><img width=\"100%\" class=\"line5\" height=\"3\" src=\"" . Theme::theme()->parameter('image-hline') . "\" alt=\"\">"; echo "</td>"; // spouse information echo "<td style=\"vertical-align: center;"; if (!empty($divrec)) { echo " filter:alpha(opacity=40);opacity:0.4;\">"; } else { echo "\">"; } FunctionsPrint::printPedigreePerson($spouse, $show_full); echo "</td>"; // cousins if ($show_cousins) { self::printCousins($famid_child, $show_full); } } } echo "</tr>"; } } elseif ($sosa < 1) { // message 'no children' except for sosa if (preg_match('/\\n1 NCHI (\\d+)/', $family->getGedcom(), $match) && $match[1] == 0) { echo '<tr><td><i class="icon-childless"></i> ' . I18N::translate('This family remained childless') . '</td></tr>'; } } echo "</table><br>"; }
/** * Print a family group. * * @param Family $family * @param string $type * @param string $label */ private function printFamily(Family $family, $type, $label) { global $controller; if ($family->getTree()->getPreference('SHOW_PRIVATE_RELATIONSHIPS')) { $access_level = Auth::PRIV_HIDE; } else { $access_level = Auth::accessLevel($family->getTree()); } ?> <table> <tr> <td> <i class="icon-cfamily"></i> </td> <td> <span class="subheaders"> <?php echo $label; ?> </span> <a class="noprint" href="<?php echo $family->getHtmlUrl(); ?> "> - <?php echo I18N::translate('View this family'); ?> </a> </td> </tr> </table> <table class="facts_table"> <?php ///// HUSB ///// $found = false; foreach ($family->getFacts('HUSB', false, $access_level) as $fact) { $found |= !$fact->isPendingDeletion(); $person = $fact->getTarget(); if ($person instanceof Individual) { if ($fact->isPendingAddition()) { $class = 'facts_label new'; } elseif ($fact->isPendingDeletion()) { $class = 'facts_label old'; } else { $class = 'facts_label'; } ?> <tr> <td class="<?php echo $class; ?> "> <?php echo Functions::getCloseRelationshipName($controller->record, $person); ?> </td> <td class="<?php echo $controller->getPersonStyle($person); ?> "> <?php echo Theme::theme()->individualBoxLarge($person); ?> </td> </tr> <?php } } if (!$found && $family->canEdit()) { ?> <tr> <td class="facts_label"></td> <td class="facts_value"><a href="#" onclick="return add_spouse_to_family('<?php echo $family->getXref(); ?> ', 'HUSB');"><?php echo I18N::translate('Add a husband to this family'); ?> </a></td> </tr> <?php } ///// WIFE ///// $found = false; foreach ($family->getFacts('WIFE', false, $access_level) as $fact) { $person = $fact->getTarget(); if ($person instanceof Individual) { $found |= !$fact->isPendingDeletion(); if ($fact->isPendingAddition()) { $class = 'facts_label new'; } elseif ($fact->isPendingDeletion()) { $class = 'facts_label old'; } else { $class = 'facts_label'; } ?> <tr> <td class="<?php echo $class; ?> "> <?php echo Functions::getCloseRelationshipName($controller->record, $person); ?> </td> <td class="<?php echo $controller->getPersonStyle($person); ?> "> <?php echo Theme::theme()->individualBoxLarge($person); ?> </td> </tr> <?php } } if (!$found && $family->canEdit()) { ?> <tr> <td class="facts_label"></td> <td class="facts_value"><a href="#" onclick="return add_spouse_to_family('<?php echo $family->getXref(); ?> ', 'WIFE');"><?php echo I18N::translate('Add a wife to this family'); ?> </a></td> </tr> <?php } ///// MARR ///// $found = false; $prev = new Date(''); foreach ($family->getFacts(WT_EVENTS_MARR . '|' . WT_EVENTS_DIV, true) as $fact) { $found |= !$fact->isPendingDeletion(); if ($fact->isPendingAddition()) { $class = ' new'; } elseif ($fact->isPendingDeletion()) { $class = ' old'; } else { $class = ''; } ?> <tr> <td class="facts_label"> </td> <td class="facts_value<?php echo $class; ?> "> <?php echo GedcomTag::getLabelValue($fact->getTag(), $fact->getDate()->display() . ' — ' . $fact->getPlace()->getFullName()); ?> </td> </tr> <?php if (!$prev->isOK() && $fact->getDate()->isOK()) { $prev = $fact->getDate(); } } if (!$found && $family->canShow() && $family->canEdit()) { // Add a new marriage ?> <tr> <td class="facts_label"> </td> <td class="facts_value"> <a href="#" onclick="return add_new_record('<?php echo $family->getXref(); ?> ', 'MARR');"> <?php echo I18N::translate('Add marriage details'); ?> </a> </td> </tr> <?php } ///// CHIL ///// $child_number = 0; foreach ($family->getFacts('CHIL', false, $access_level) as $fact) { $person = $fact->getTarget(); if ($person instanceof Individual) { if ($fact->isPendingAddition()) { $child_number++; $class = 'facts_label new'; } elseif ($fact->isPendingDeletion()) { $class = 'facts_label old'; } else { $child_number++; $class = 'facts_label'; } $next = new Date(''); foreach ($person->getFacts(WT_EVENTS_BIRT, true) as $bfact) { if ($bfact->getDate()->isOK()) { $next = $bfact->getDate(); break; } } ?> <tr> <td class="<?php echo $class; ?> "> <?php echo self::ageDifference($prev, $next, $child_number); ?> <?php echo Functions::getCloseRelationshipName($controller->record, $person); ?> </td> <td class="<?php echo $controller->getPersonStyle($person); ?> "> <?php echo Theme::theme()->individualBoxLarge($person); ?> </td> </tr> <?php $prev = $next; } } // Re-order children / add a new child if ($family->canEdit()) { if ($type == 'FAMS') { $add_child_text = I18N::translate('Add a son or daughter'); } else { $add_child_text = I18N::translate('Add a brother or sister'); } ?> <tr class="noprint"> <td class="facts_label"> <?php if (count($family->getChildren()) > 1) { ?> <a href="#" onclick="reorder_children('<?php echo $family->getXref(); ?> ');tabswitch(5);"><i class="icon-media-shuffle"></i> <?php echo I18N::translate('Re-order children'); ?> </a> <?php } ?> </td> <td class="facts_value"> <a href="#" onclick="return add_child_to_family('<?php echo $family->getXref(); ?> ');"><?php echo $add_child_text; ?> </a> <span style='white-space:nowrap;'> <a href="#" class="icon-sex_m_15x15" onclick="return add_child_to_family('<?php echo $family->getXref(); ?> ','M');"></a> <a href="#" class="icon-sex_f_15x15" onclick="return add_child_to_family('<?php echo $family->getXref(); ?> ','F');"></a> </span> </td> </tr> <?php } echo '</table>'; return; }