/** * Startup activity * * @param GedcomRecord|null $record */ public function __construct(GedcomRecord $record = null) { $this->record = $record; // 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')); } }
/** * Generate the HTML content of this block. * * @param int $block_id * @param bool $template * @param string[] $cfg * * @return string */ public function getBlock($block_id, $template = true, $cfg = array()) { global $ctype, $controller, $WT_TREE; $days = $this->getBlockSetting($block_id, 'days', '7'); $infoStyle = $this->getBlockSetting($block_id, 'infoStyle', 'table'); $calendar = $this->getBlockSetting($block_id, 'calendar', 'jewish'); $block = $this->getBlockSetting($block_id, 'block', '1'); foreach (array('days', 'infoStyle', 'block') as $name) { if (array_key_exists($name, $cfg)) { ${$name} = $cfg[$name]; } } $startjd = WT_CLIENT_JD; $endjd = WT_CLIENT_JD + $days - 1; $id = $this->getName() . $block_id; $class = $this->getName() . '_block'; if ($ctype === 'gedcom' && Auth::isManager($WT_TREE) || $ctype === 'user' && Auth::check()) { $title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&ged=' . $WT_TREE->getNameHtml() . '&ctype=' . $ctype . '"></a>'; } else { $title = ''; } $title .= $this->getTitle(); $content = ''; // The standard anniversary rules cover most of the Yahrzeit rules, we just // need to handle a few special cases. // Fetch normal anniversaries... $yahrzeits = array(); for ($jd = $startjd - 1; $jd <= $endjd + $days; ++$jd) { foreach (FunctionsDb::getAnniversaryEvents($jd, 'DEAT _YART', $WT_TREE) as $fact) { // Exact hebrew dates only $date = $fact->getDate(); if ($date->minimumDate() instanceof JewishDate && $date->minimumJulianDay() === $date->maximumJulianDay()) { $fact->jd = $jd; $yahrzeits[] = $fact; } } } // ...then adjust dates $jewish_calendar = new JewishCalendar(); foreach ($yahrzeits as $yahrzeit) { if ($yahrzeit->getTag() === 'DEAT') { $today = new JewishDate($yahrzeit->jd); $hd = $yahrzeit->getDate()->minimumDate(); $hd1 = new JewishDate($hd); $hd1->y += 1; $hd1->setJdFromYmd(); // Special rules. See http://www.hebcal.com/help/anniv.html // Everything else is taken care of by our standard anniversary rules. if ($hd->d == 30 && $hd->m == 2 && $hd->y != 0 && $hd1->daysInMonth() < 30) { // 30 CSH - Last day in CSH $yahrzeit->jd = $jewish_calendar->ymdToJd($today->y, 3, 1) - 1; } elseif ($hd->d == 30 && $hd->m == 3 && $hd->y != 0 && $hd1->daysInMonth() < 30) { // 30 KSL - Last day in KSL $yahrzeit->jd = $jewish_calendar->ymdToJd($today->y, 4, 1) - 1; } elseif ($hd->d == 30 && $hd->m == 6 && $hd->y != 0 && $today->daysInMonth() < 30 && !$today->isLeapYear()) { // 30 ADR - Last day in SHV $yahrzeit->jd = $jewish_calendar->ymdToJd($today->y, 6, 1) - 1; } } } switch ($infoStyle) { case 'list': foreach ($yahrzeits as $yahrzeit) { if ($yahrzeit->jd >= $startjd && $yahrzeit->jd < $startjd + $days) { $ind = $yahrzeit->getParent(); $content .= "<a href=\"" . $ind->getHtmlUrl() . "\" class=\"list_item name2\">" . $ind->getFullName() . "</a>" . $ind->getSexImage(); $content .= "<div class=\"indent\">"; $content .= $yahrzeit->getDate()->display(true); $content .= ', ' . I18N::translate('%s year anniversary', $yahrzeit->anniv); $content .= "</div>"; } } break; case 'table': default: $table_id = Uuid::uuid4(); // table requires a unique ID $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addInlineJavascript(' jQuery("#' . $table_id . '").dataTable({ dom: \'t\', ' . I18N::datatablesI18N() . ', autoWidth: false, paginate: false, lengthChange: false, filter: false, info: true, jQueryUI: true, sorting: [[5,"asc"]], columns: [ /* 0-name */ { dataSort: 1 }, /* 1-NAME */ { visible: false }, /* 2-date */ { dataSort: 3 }, /* 3-DATE */ { visible: false }, /* 4-Aniv */ { class: "center"}, /* 5-yart */ { dataSort: 6 }, /* 6-YART */ { visible: false } ] }); jQuery("#' . $table_id . '").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); $content = ''; $content .= '<div class="loading-image"> </div>'; $content .= '<table id="' . $table_id . '" class="width100" style="visibility:hidden;">'; $content .= '<thead><tr>'; $content .= '<th>' . GedcomTag::getLabel('NAME') . '</th>'; $content .= '<th>' . GedcomTag::getLabel('NAME') . '</th>'; $content .= '<th>' . GedcomTag::getLabel('DEAT') . '</th>'; $content .= '<th>DEAT</th>'; $content .= '<th><i class="icon-reminder" title="' . I18N::translate('Anniversary') . '"></i></th>'; $content .= '<th>' . GedcomTag::getLabel('_YART') . '</th>'; $content .= '<th>_YART</th>'; $content .= '</tr></thead><tbody>'; foreach ($yahrzeits as $yahrzeit) { if ($yahrzeit->jd >= $startjd && $yahrzeit->jd < $startjd + $days) { $content .= '<tr>'; $ind = $yahrzeit->getParent(); // Individual name(s) $name = $ind->getFullName(); $url = $ind->getHtmlUrl(); $content .= '<td>'; $content .= '<a href="' . $url . '">' . $name . '</a>'; $content .= $ind->getSexImage(); $addname = $ind->getAddName(); if ($addname) { $content .= '<br><a href="' . $url . '">' . $addname . '</a>'; } $content .= '</td>'; $content .= '<td>' . $ind->getSortName() . '</td>'; // death/yahrzeit event date $content .= '<td>' . $yahrzeit->getDate()->display() . '</td>'; $content .= '<td>' . $yahrzeit->getDate()->julianDay() . '</td>'; // sortable date // Anniversary $content .= '<td>' . $yahrzeit->anniv . '</td>'; // upcomming yahrzeit dates switch ($calendar) { case 'gregorian': $today = new GregorianDate($yahrzeit->jd); break; case 'jewish': default: $today = new JewishDate($yahrzeit->jd); break; } $td = new Date($today->format('%@ %A %O %E')); $content .= '<td>' . $td->display() . '</td>'; $content .= '<td>' . $td->julianDay() . '</td>'; // sortable date $content .= '</tr>'; } } $content .= '</tbody></table>'; break; } if ($template) { if ($block) { $class .= ' small_inner_block'; } return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
?> </option> <option value="BURI" <?php echo $filterev === 'BURI' ? 'selected' : ''; ?> > <?php echo GedcomTag::getLabel('BURI'); ?> </option> <option value="IMMI,EMIG" <?php echo $filterev === 'IMMI,EMIG' ? 'selected' : ''; ?> > <?php echo GedcomTag::getLabel('EMIG'); ?> </option> <option value="EVEN" <?php echo $filterev === 'EVEN' ? 'selected' : ''; ?> > <?php echo I18N::translate('Custom event'); ?> </option> </select> </td> </tr> </table>
/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { if ($this->data->get('has_sosa', false)) { $table_id = $this->data->get('table_id'); ?> <div id="sosa-fam-list" class="sosa-list"> <table id="<?php echo $table_id; ?> "> <thead> <tr> <th colspan="24"> <div class="btn-toolbar"> <div class="btn-group"> <button type="button" data-filter-column="22" data-filter-value="N" class="ui-state-default" title="<?php echo I18N::translate('Show individuals who are alive or couples where both partners are alive.'); ?> " > <?php echo I18N::translate('Both alive'); ?> </button> <button type="button" data-filter-column="22" data-filter-value="W" class="ui-state-default" title="<?php echo I18N::translate('Show couples where only the female partner is deceased.'); ?> " > <?php echo I18N::translate('Widower'); ?> </button> <button type="button" data-filter-column="22" data-filter-value="H" class="ui-state-default" title="<?php echo I18N::translate('Show couples where only the male partner is deceased.'); ?> " > <?php echo I18N::translate('Widow'); ?> </button> <button type="button" data-filter-column="22" data-filter-value="Y" class="ui-state-default" title="<?php echo I18N::translate('Show individuals who are dead or couples where both partners are deceased.'); ?> " > <?php echo I18N::translate('Both dead'); ?> </button> </div> <div class="btn-group"> <button type="button" data-filter-column="23" data-filter-value="R" class="ui-state-default" title="<?php echo I18N::translate('Show “roots” couples or individuals. These individuals may also be called “patriarchs”. They are individuals who have no parents recorded in the database.'); ?> " > <?php echo I18N::translate('Roots'); ?> </button> <button type="button" data-filter-column="23" data-filter-value="L" class="ui-state-default" title="<?php echo I18N::translate('Show “leaves” couples or individuals. These are individuals who are alive but have no children recorded in the database.'); ?> " > <?php echo I18N::translate('Leaves'); ?> </button> </div> <div class="btn-group"> <button type="button" data-filter-column="21" data-filter-value="U" class="ui-state-default" title="<?php echo I18N::translate('Show couples with an unknown marriage date.'); ?> " > <?php echo GedcomTag::getLabel('MARR'); ?> </button> <button type="button" data-filter-column="21" data-filter-value="YES" class="ui-state-default" title="<?php echo I18N::translate('Show couples who married more than 100 years ago.'); ?> " > <?php echo GedcomTag::getLabel('MARR'); ?> >100 </button> <button type="button" data-filter-column="21" data-filter-value="Y100" class="ui-state-default" title="<?php echo I18N::translate('Show couples who married within the last 100 years.'); ?> " > <?php echo GedcomTag::getLabel('MARR'); ?> <=100 </button> <button type="button" data-filter-column="21" data-filter-value="D" class="ui-state-default" title="<?php echo I18N::translate('Show divorced couples.'); ?> " > <?php echo GedcomTag::getLabel('DIV'); ?> </button> <button type="button" data-filter-column="21" data-filter-value="M" class="ui-state-default" title="<?php echo I18N::translate('Show couples where either partner married more than once.'); ?> " > <?php echo I18N::translate('Multiple marriages'); ?> </button> </div> </div> </th> </tr> <tr> <th><?php echo I18N::translate('Sosa'); ?> </th> <th>SOSA</th> <th><?php echo GedcomTag::getLabel('GIVN'); ?> </th> <th><?php echo GedcomTag::getLabel('SURN'); ?> </th> <th>HUSB:GIVN_SURN</th> <th>HUSB:SURN_GIVN</th> <th><?php echo GedcomTag::getLabel('AGE'); ?> </th> <th>AGE</th> <th><?php echo GedcomTag::getLabel('GIVN'); ?> </th> <th><?php echo GedcomTag::getLabel('SURN'); ?> </th> <th>WIFE:GIVN_SURN</th> <th>WIFE:SURN_GIVN</th> <th><?php echo GedcomTag::getLabel('AGE'); ?> </th> <th>AGE</th> <th><?php echo GedcomTag::getLabel('MARR'); ?> </th> <th>MARR:DATE</th> <th><?php echo GedcomTag::getLabel('PLAC'); ?> </th>'; <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { ?> <th><i class="icon-source" title="<?php echo I18N::translate('Sourced marriage'); ?> " border="0"></i></th> <th>SORT_MARRSC</th> <?php } else { ?> <th> </th> <th></th> <?php } ?> <th><i class="icon-children" title="<?php echo I18N::translate('Children'); ?> "></i></th> <th>NCHI</th> <th>MARR</th> <th>DEAT</th> <th>TREE</th> </tr> </thead> <tbody> <?php foreach ($this->data->get('sosa_list') as $sosa => $family) { /** @var \Fisharebest\Webtrees\Family $person */ //PERSO Create decorator for Family $dfamily = new Family($family); $husb = $family->getHusband(); if (is_null($husb)) { $husb = new Individual('H', '0 @H@ INDI', null, $family->getTree()); } $dhusb = new \MyArtJaub\Webtrees\Individual($husb); $wife = $family->getWife(); if (is_null($wife)) { $wife = new Individual('W', '0 @W@ INDI', null, $family->getTree()); } $dwife = new \MyArtJaub\Webtrees\Individual($wife); $mdate = $family->getMarriageDate(); if ($family->isPendingAddtion()) { $class = ' class="new"'; } elseif ($family->isPendingDeletion()) { $class = ' class="old"'; } else { $class = ''; } ?> <tr <?php echo $class; ?> > <td class="transparent"><?php echo I18N::translate('%1$d/%2$d', $sosa, ($sosa + 1) % 10); ?> </td> <td class="transparent"><?php echo $sosa; ?> </td> <!-- HUSBAND --> <td colspan="2"> <?php foreach ($husb->getAllNames() as $num => $name) { if ($name['type'] == 'NAME') { $title = ''; } else { $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $husb)) . '"'; } if ($num == $husb->getPrimaryName()) { $class = ' class="name2"'; $sex_image = $husb->getSexImage(); list($surn, $givn) = explode(',', $name['sort']); } else { $class = ''; $sex_image = ''; } ?> <a <?php echo $title . ' ' . $class; ?> href="<?php echo $husb->getHtmlUrl(); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($name['full']); ?> </a> <?php echo $sex_image . FunctionsPrint::formatSosaNumbers($dhusb->getSosaNumbers(), 1, 'smaller'); ?> <br/> <?php } echo $husb->getPrimaryParentsNames('parents details1', 'none'); ?> </td> <!-- Dummy column to match colspan in header --> <td style="display:none;"></td> <td> <?php echo Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)); ?> </td> <td> <?php echo Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)); ?> </td> <?php $hdate = $husb->getBirthDate(); ?> <td><?php Date::getAge($hdate, $mdate, 2); ?> </td> <td><?php Date::getAge($hdate, $mdate, 1); ?> </td> <!-- WIFE --> <td colspan="2"> <?php foreach ($wife->getAllNames() as $num => $name) { if ($name['type'] == 'NAME') { $title = ''; } else { $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $wife)) . '"'; } if ($num == $wife->getPrimaryName()) { $class = ' class="name2"'; $sex_image = $wife->getSexImage(); list($surn, $givn) = explode(',', $name['sort']); } else { $class = ''; $sex_image = ''; } ?> <a <?php echo $title . ' ' . $class; ?> href="<?php echo $wife->getHtmlUrl(); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($name['full']); ?> </a> <?php echo $sex_image . FunctionsPrint::formatSosaNumbers($dwife->getSosaNumbers(), 1, 'smaller'); ?> <br/> <?php } echo $wife->getPrimaryParentsNames('parents details1', 'none'); ?> </td> <!-- Dummy column to match colspan in header --> <td style="display:none;"></td> <td> <?php echo Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)); ?> </td> <td> <?php echo Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)); ?> </td> <?php $wdate = $wife->getBirthDate(); ?> <td><?php Date::getAge($wdate, $mdate, 2); ?> </td> <td><?php Date::getAge($wdate, $mdate, 1); ?> </td> <td><?php if ($marriage_dates = $family->getAllMarriageDates()) { foreach ($marriage_dates as $n => $marriage_date) { if ($n) { echo '<br>'; } ?> <div><?php echo $marriage_date->display(true); ?> </div> <?php } } elseif ($family->getFacts('_NMR')) { echo I18N::translate('no'); } elseif ($family->getFacts('MARR')) { echo I18N::translate('yes'); } else { echo ' '; } ?> </td> <td><?php echo $marriage_dates ? $marriage_date->julianDay() : 0; ?> </td> <td><?php foreach ($family->getAllMarriagePlaces() as $n => $marriage_place) { $tmp = new Place($marriage_place, $family->getTree()); if ($n) { ?> <br><?php } ?> <a href="'<?php echo $tmp->getURL(); ?> " title="<?php echo strip_tags($tmp->getFullName()); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName()); ?> </a> <?php } ?> </td> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { $isMSourced = $dfamily->isMarriageSourced(); ?> <td><?php echo FunctionsPrint::formatIsSourcedIcon('E', $isMSourced, 'MARR', 1, 'medium'); ?> </td> <td><?php echo $isMSourced; ?> </td> <?php } else { ?> <td> </td> <td></td> <?php } ?> <?php $nchi = $family->getNumberOfChildren(); ?> <td><?php echo I18N::number($nchi); ?> </td> <td><?php echo $nchi; ?> </td> <td><?php if (!$mdate->isOK()) { echo 'U'; } else { if (Date::compare($mdate, new Date(date('Y') - 100)) > 0) { echo 'Y100'; } else { echo 'YES'; } } if ($family->getFacts(WT_EVENTS_DIV)) { echo 'D'; } if (count($husb->getSpouseFamilies()) > 1 || count($wife->getSpouseFamilies()) > 1) { echo 'M'; } ?> </td> <td><?php if ($husb->isDead() && $wife->isDead()) { echo 'Y'; } if ($husb->isDead() && !$wife->isDead()) { if ($wife->getSex() == 'F') { echo 'H'; } if ($wife->getSex() == 'M') { echo 'W'; } // male partners } if (!$husb->isDead() && $wife->isDead()) { if ($husb->getSex() == 'M') { echo 'W'; } if ($husb->getSex() == 'F') { echo 'H'; } // female partners } if (!$husb->isDead() && !$wife->isDead()) { echo 'N'; } ?> </td> <td><?php if (!$husb->getChildFamilies() && !$wife->getChildFamilies()) { echo 'R'; } elseif (!$husb->isDead() && !$wife->isDead() && $family->getNumberOfChildren() < 1) { echo 'L'; } else { echo ' '; } ?> </td> </tr> <?php } ?> </tbody> <tfoot> <tr> <th colspan="24"> <div class="btn-toolbar"> <div class="btn-group"> <button type="button" class="ui-state-default btn-toggle-parents"> <?php echo I18N::translate('Show parents'); ?> </button> <button id="btn-toggle-statistics-<?php echo $table_id; ?> " type="button" class="ui-state-default btn-toggle-statistics"> <?php echo I18N::translate('Show statistics charts'); ?> </button> </div> </div> </th> </tr> </tfoot> </table> <div id="fam_list_table-charts_<?php echo $table_id; ?> " style="display:none"> <table class="list-charts"> <tr> <td><?php echo $this->data->get('chart_births'); ?> </td> <td><?php echo $this->data->get('chart_marriages'); ?> </td> </tr> <tr> <td colspan="2"><?php echo $this->data->get('chart_ages'); ?> </td> </tr> </table> </div> </div> <?php } else { ?> <p class="warning"><?php echo I18N::translate('No family has been found for generation %d', $this->data->get('generation')); ?> </p> <?php } }
/** * 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>'; }
} ?> ><?php echo I18N::translate('Sounds like'); ?> </option> </select> </td> <?php $j++; ?> </tr> <tr> <td class="list_label"> <?php echo GedcomTag::getLabel('SURN'); ?> </td> <td class="list_value"> <input type="text" name="values[<?php echo $j; ?> ]" value="<?php echo $controller->getValue($controller->getIndex('FAMC:WIFE:NAME:SURN:' . $motherSurnOption)); ?> "> <select name="fields[<?php echo $j; ?> ]"> <option value="FAMC:WIFE:NAME:SURN:EXACT" <?php
/** * Generate a recursive list of descendants of an individual. * If parents are specified, we can also show the pedigree (adopted, etc.). * * @param Individual $individual * @param Family|null $parents * * @return string */ private function getDescendantsHtml(Individual $individual, Family $parents = null) { // A person has many names. Select the one that matches the searched surname $person_name = ''; foreach ($individual->getAllNames() as $name) { list($surn1) = explode(",", $name['sort']); if (stripos($surn1, $this->surname) !== false || stripos($this->surname, $surn1) !== false || $this->soundex_std && Soundex::compare(Soundex::russell($surn1), Soundex::russell($this->surname)) || $this->soundex_dm && Soundex::compare(Soundex::daitchMokotoff($surn1), Soundex::daitchMokotoff($this->surname))) { $person_name = $name['full']; break; } } // No matching name? Typically children with a different surname. The branch stops here. if (!$person_name) { return '<li title="' . strip_tags($individual->getFullName()) . '">' . $individual->getSexImage() . '…</li>'; } // Is this individual one of our ancestors? $sosa = array_search($individual, $this->ancestors, true); if ($sosa) { $sosa_class = 'search_hit'; $sosa_html = ' <a class="details1 ' . $individual->getBoxStyle() . '" title="' . I18N::translate('Sosa') . '" href="relationship.php?pid2=' . $this->ancestors[1]->getXref() . '&pid1=' . $individual->getXref() . '">' . $sosa . '</a>' . self::sosaGeneration($sosa); } else { $sosa_class = ''; $sosa_html = ''; } // Generate HTML for this individual, and all their descendants $indi_html = $individual->getSexImage() . '<a class="' . $sosa_class . '" href="' . $individual->getHtmlUrl() . '">' . $person_name . '</a> ' . $individual->getLifeSpan() . $sosa_html; // If this is not a birth pedigree (e.g. an adoption), highlight it if ($parents) { $pedi = ''; foreach ($individual->getFacts('FAMC') as $fact) { if ($fact->getTarget() === $parents) { $pedi = $fact->getAttribute('PEDI'); break; } } if ($pedi && $pedi != 'birth') { $indi_html = '<span class="red">' . GedcomCodePedi::getValue($pedi, $individual) . '</span> ' . $indi_html; } } // spouses and children $spouse_families = $individual->getSpouseFamilies(); if ($spouse_families) { usort($spouse_families, '\\Fisharebest\\Webtrees\\Family::compareMarrDate'); $fam_html = ''; foreach ($spouse_families as $family) { $fam_html .= $indi_html; // Repeat the individual details for each spouse. $spouse = $family->getSpouse($individual); if ($spouse) { $sosa = array_search($spouse, $this->ancestors, true); if ($sosa) { $sosa_class = 'search_hit'; $sosa_html = ' <a class="details1 ' . $spouse->getBoxStyle() . '" title="' . I18N::translate('Sosa') . '" href="relationship.php?pid2=' . $this->ancestors[1]->getXref() . '&pid1=' . $spouse->getXref() . '"> ' . $sosa . ' </a>' . self::sosaGeneration($sosa); } else { $sosa_class = ''; $sosa_html = ''; } $marriage_year = $family->getMarriageYear(); if ($marriage_year) { $fam_html .= ' <a href="' . $family->getHtmlUrl() . '" title="' . strip_tags($family->getMarriageDate()->display()) . '"><i class="icon-rings"></i>' . $marriage_year . '</a>'; } elseif ($family->getFirstFact('MARR')) { $fam_html .= ' <a href="' . $family->getHtmlUrl() . '" title="' . GedcomTag::getLabel('MARR') . '"><i class="icon-rings"></i></a>'; } elseif ($family->getFirstFact('_NMR')) { $fam_html .= ' <a href="' . $family->getHtmlUrl() . '" title="' . GedcomTag::getLabel('_NMR') . '"><i class="icon-rings"></i></a>'; } $fam_html .= ' ' . $spouse->getSexImage() . '<a class="' . $sosa_class . '" href="' . $spouse->getHtmlUrl() . '">' . $spouse->getFullName() . '</a> ' . $spouse->getLifeSpan() . ' ' . $sosa_html; } $fam_html .= '<ol>'; foreach ($family->getChildren() as $child) { $fam_html .= $this->getDescendantsHtml($child, $family); } $fam_html .= '</ol>'; } return '<li>' . $fam_html . '</li>'; } else { // No spouses - just show the individual return '<li>' . $indi_html . '</li>'; } }
/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { if ($this->data->get('has_sosa', false)) { $table_id = $this->data->get('table_id'); ?> <div id="sosa-indi-list" class="sosa-list"> <table id="<?php echo $table_id; ?> "> <thead> <tr> <th colspan="22"> <div class="btn-toolbar"> <div class="btn-group"> <button class="ui-state-default" data-filter-column="18" data-filter-value="M" title="<?php echo I18N::translate('Show only males.'); ?> " type="button" ><?php echo Individual::sexImage('M', 'large'); ?> </button> <button class="ui-state-default" data-filter-column="18" data-filter-value="F" title="<?php echo I18N::translate('Show only females.'); ?> " type="button" > <?php echo Individual::sexImage('F', 'large'); ?> </button> <button class="ui-state-default" data-filter-column="18" data-filter-value="U" title="<?php echo I18N::translate('Show only individuals for whom the gender is not known.'); ?> " type="button" > <?php echo Individual::sexImage('U', 'large'); ?> </button> </div> <div class="btn-group"> <button class="ui-state-default" data-filter-column="20" data-filter-value="N" title="<?php echo I18N::translate('Show individuals who are alive or couples where both partners are alive.'); ?> " type="button" > <?php echo I18N::translate('Alive'); ?> </button> <button class="ui-state-default" data-filter-column="20" data-filter-value="Y" title="<?php echo I18N::translate('Show individuals who are dead or couples where both partners are deceased.'); ?> " type="button" > <?php echo I18N::translate('Dead'); ?> </button> <button class="ui-state-default" data-filter-column="20" data-filter-value="YES" title="<?php echo I18N::translate('Show individuals who died more than 100 years ago.'); ?> " type="button" ><?php echo GedcomTag::getLabel('DEAT'); ?> >100 </button> <button class="ui-state-default" data-filter-column="20" data-filter-value="Y100" title="<?php echo I18N::translate('Show individuals who died within the last 100 years.'); ?> " type="button" ><?php echo GedcomTag::getLabel('DEAT'); ?> <=100 </button> </div> <div class="btn-group"> <button class="ui-state-default" data-filter-column="19" data-filter-value="YES" title="<?php echo I18N::translate('Show individuals born more than 100 years ago.'); ?> " type="button" ><?php echo GedcomTag::getLabel('BIRT'); ?> >100 </button> <button class="ui-state-default" data-filter-column="19" data-filter-value="Y100" title="<?php echo I18N::translate('Show individuals born within the last 100 years.'); ?> " type="button" ><?php echo GedcomTag::getLabel('BIRT'); ?> <=100 </button> </div> <div class="btn-group"> <button class="ui-state-default" data-filter-column="21" data-filter-value="R" title="<?php echo I18N::translate('Show “roots” couples or individuals. These individuals may also be called “patriarchs”. They are individuals who have no parents recorded in the database.'); ?> " type="button" > <?php echo I18N::translate('Roots'); ?> </button> <button class="ui-state-default" data-filter-column="21" data-filter-value="L" title="<?php echo I18N::translate('Show “leaves” couples or individuals. These are individuals who are alive but have no children recorded in the database.'); ?> " type="button" > <?php echo I18N::translate('Leaves'); ?> </button> </div> </div> </th> </tr> <tr> <th><?php echo I18N::translate('Sosa'); ?> </th> <th><?php echo GedcomTag::getLabel('INDI'); ?> </th> <th><?php echo GedcomTag::getLabel('GIVN'); ?> </th> <th><?php echo GedcomTag::getLabel('SURN'); ?> </th> <th>GIVN</th> <th>SURN</th> <th><?php echo GedcomTag::getLabel('BIRT'); ?> </th> <th>SORT_BIRT</th> <th><?php echo GedcomTag::getLabel('PLAC'); ?> </th> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { ?> <th><i class="icon-source" title="<?php echo I18N::translate('Sourced birth'); ?> " border="0"></i></th> <th>SORT_BIRTSC</th> <?php } else { ?> <th></th> <th></th> <?php } ?> <th><?php echo GedcomTag::getLabel('DEAT'); ?> </th> <th>SORT_DEAT</th> <th><?php echo GedcomTag::getLabel('AGE'); ?> </th> <th>AGE</th> <th><?php echo GedcomTag::getLabel('PLAC'); ?> </th> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { ?> <th><i class="icon-source" title="<?php echo I18N::translate('Sourced death'); ?> " border="0"></i></th> <th>SORT_DEATSC</th> <?php } else { ?> <th></th> <th></th> <?php } ?> <th>SEX</th> <th>BIRT</th> <th>DEAT</th> <th>TREE</th> </tr> </thead> <tbody> <?php foreach ($this->data->get('sosa_list') as $sosa => $person) { /** @var \Fisharebest\Webtrees\Individual $person */ if ($person->isPendingAddtion()) { $class = ' class="new"'; } elseif ($person->isPendingDeletion()) { $class = ' class="old"'; } else { $class = ''; } $dperson = new \MyArtJaub\Webtrees\Individual($person); ?> <tr <?php echo $class; ?> > <td class="transparent"><?php echo $sosa; ?> </td> <td class="transparent"><?php echo $person->getXref(); ?> </td> <td colspan="2"> <?php foreach ($person->getAllNames() as $num => $name) { if ($name['type'] == 'NAME') { $title = ''; } else { $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $person)) . '"'; } if ($num == $person->getPrimaryName()) { $class = ' class="name2"'; $sex_image = $person->getSexImage(); list($surn, $givn) = explode(',', $name['sort']); } else { $class = ''; $sex_image = ''; } ?> <a <?php echo $title . ' ' . $class; ?> href="<?php echo $person->getHtmlUrl(); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($name['full']); ?> </a> <?php echo $sex_image . FunctionsPrint::formatSosaNumbers($dperson->getSosaNumbers(), 1, 'smaller'); ?> <br/> <?php } echo $person->getPrimaryParentsNames('parents details1', 'none'); ?> </td> <td style="display:none;"></td> <td> <?php echo Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)); ?> </td> <td> <?php echo Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)); ?> </td> <td> <?php if ($birth_dates = $person->getAllBirthDates()) { foreach ($birth_dates as $num => $birth_date) { if ($num) { ?> <br/><?php } ?> <?php echo $birth_date->display(true); } } else { $birth_date = new Date(''); if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES')) { $birth_date = $person->getEstimatedBirthDate(); echo $birth_date->display(true); } else { echo ' '; } $birth_dates[0] = new Date(''); } ?> </td> <td><?php echo $birth_date->julianDay(); ?> </td> <td> <?php foreach ($person->getAllBirthPlaces() as $n => $birth_place) { $tmp = new \Fisharebest\Webtrees\Place($birth_place, $person->getTree()); if ($n) { ?> <br><?php } ?> <a href="'<?php echo $tmp->getURL(); ?> " title="<?php echo strip_tags($tmp->getFullName()); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName()); ?> </a> <?php } ?> </td> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { $isBSourced = $dperson->isBirthSourced(); ?> <td><?php echo FunctionsPrint::formatIsSourcedIcon('E', $isBSourced, 'BIRT', 1, 'medium'); ?> </td> <td><?php echo $isBSourced; ?> </td> <?php } else { ?> <td> </td> <td></td> <?php } ?> <td> <?php if ($death_dates = $person->getAllDeathDates()) { foreach ($death_dates as $num => $death_date) { if ($num) { ?> <br/><?php } ?> <?php echo $death_date->display(true); } } else { $death_date = $person->getEstimatedDeathDate(); if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES') && $death_date->minimumJulianDay() < WT_CLIENT_JD) { echo $death_date->display(true); } elseif ($person->isDead()) { echo I18N::translate('yes'); $death_date = new Date(''); } else { echo ' '; $death_date = new Date(''); } $death_dates[0] = new Date(''); } ?> </td> <td><?php echo $death_date->julianDay(); ?> </td> <td><?php echo Date::getAge($birth_dates[0], $death_dates[0], 2); ?> </td> <td><?php echo Date::getAge($birth_dates[0], $death_dates[0], 1); ?> </td> <td> <?php foreach ($person->getAllDeathPlaces() as $n => $death_place) { $tmp = new Place($death_place, $person->getTree()); if ($n) { ?> <br><?php } ?> <a href="'<?php echo $tmp->getURL(); ?> " title="<?php echo strip_tags($tmp->getFullName()); ?> "> <?php echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName()); ?> </a> <?php } ?> </td> <?php if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) { $isDSourced = $dperson->isDeathSourced(); ?> <td><?php echo FunctionsPrint::formatIsSourcedIcon('E', $isDSourced, 'DEAT', 1, 'medium'); ?> </td> <td><?php echo $isDSourced; ?> </td> <?php } else { ?> <td> </td> <td></td> <?php } ?> <td><?php echo $person->getSex(); ?> </td> <td> <?php if (!$person->canShow() || Date::compare($birth_date, new Date(date('Y') - 100)) > 0) { echo 'Y100'; } else { echo 'YES'; } ?> </td> <td> <?php if (Date::compare($death_dates[0], new Date(date('Y') - 100)) > 0) { echo 'Y100'; } elseif ($death_dates[0]->minimumJulianDay() || $person->isDead()) { echo 'YES'; } else { echo 'N'; } ?> </td> <td> <?php if (!$person->getChildFamilies()) { echo 'R'; } elseif (!$person->isDead() && $person->getNumberOfChildren() < 1) { echo 'L'; } else { echo ' '; } ?> </td> </tr> <?php } ?> </tbody> <tfoot> <tr> <th class="ui-state-default" colspan="22"> <div class="center"> <?php echo I18N::translate('Number of Sosa ancestors: %1$s known / %2$s theoretical (%3$s)', I18N::number($this->data->get('sosa_count')), I18N::number($this->data->get('sosa_theo')), I18N::percentage($this->data->get('sosa_ratio'), 2)); ?> <?php if ($this->data->get('sosa_hidden') > 0) { echo '[' . I18N::translate('%s hidden', I18N::number($this->data->get('sosa_hidden'))) . ']'; } ?> </div> </th> </tr> <tr> <th colspan="22"> <div class="btn-toolbar"> <div class="btn-group"> <button type="button" class="ui-state-default btn-toggle-parents"> <?php echo I18N::translate('Show parents'); ?> </button> <button id="btn-toggle-statistics-<?php echo $table_id; ?> " type="button" class="ui-state-default btn-toggle-statistics"> <?php echo I18N::translate('Show statistics charts'); ?> </button> </div> </div> </th> </tr> </tfoot> </table> <div id="indi_list_table-charts_<?php echo $table_id; ?> " style="display:none"> <table class="list-charts"> <tr> <td><?php echo $this->data->get('chart_births'); ?> </td> <td><?php echo $this->data->get('chart_deaths'); ?> </td> </tr> <tr> <td colspan="2"><?php echo $this->data->get('chart_ages'); ?> </td> </tr> </table> </div> </div> <?php } }
/** * Display an icon for this fact. * * @param Fact $fact * * @return string */ public function icon(Fact $fact) { $icon = 'images/facts/' . $fact->getTag() . '.png'; $dir = substr($this->assetUrl(), strlen(WT_STATIC_URL)); if (file_exists($dir . $icon)) { return '<img src="' . $this->assetUrl() . $icon . '" title="' . GedcomTag::getLabel($fact->getTag()) . '">'; } elseif (file_exists($dir . 'images/facts/NULL.png')) { // Spacer image - for alignment - until we move to a sprite. return '<img src="' . Theme::theme()->assetUrl() . 'images/facts/NULL.png">'; } else { return ''; } }
// Sort the facts usort($facts, function (Fact $x, Fact $y) { static $order = array('TITL' => 0, 'ABBR' => 1, 'AUTH' => 2, 'DATA' => 3, 'PUBL' => 4, 'TEXT' => 5, 'NOTE' => 6, 'OBJE' => 7, 'REFN' => 8, 'RIN' => 9, '_UID' => 10, 'CHAN' => 11); return (array_key_exists($x->getTag(), $order) ? $order[$x->getTag()] : PHP_INT_MAX) - (array_key_exists($y->getTag(), $order) ? $order[$y->getTag()] : PHP_INT_MAX); }); // Print the facts foreach ($facts as $fact) { FunctionsPrintFacts::printFact($fact, $controller->record); } // new fact link if ($controller->record->canEdit()) { FunctionsPrint::printAddNewFact($controller->record->getXref(), $facts, 'SOUR'); // new media if ($controller->record->getTree()->getPreference('MEDIA_UPLOAD') >= Auth::accessLevel($WT_TREE)) { echo '<tr><td class="descriptionbox">'; echo GedcomTag::getLabel('OBJE'); echo '</td><td class="optionbox">'; echo '<a href="#" onclick="window.open(\'addmedia.php?action=showmediaform&linktoid=', $controller->record->getXref(), '\', \'_blank\', edit_window_specs); return false;">', I18N::translate('Add a new media object'), '</a>'; echo FunctionsPrint::helpLink('OBJE'); echo '<br>'; echo '<a href="#" onclick="window.open(\'inverselink.php?linktoid=', $controller->record->getXref(), '&linkto=source\', \'_blank\', find_window_specs); return false;">', I18N::translate('Link to an existing media object'), '</a>'; echo '</td></tr>'; } } echo '</table> </div>'; // Individuals linked to this source if ($linked_indi) { echo '<div id="indi-sources">', FunctionsPrintLists::individualTable($linked_indi), '</div>'; } // Families linked to this source
/** * Format a record type. * * @param string $type * * @return string */ function format_type($type) { return '<b title="' . strip_tags(GedcomTag::getLabel($type)) . '">' . $type . '</b>'; }
<th class="descriptionbox" colspan="4"> <?php echo I18N::translate('Select individuals by place or date'); ?> </th> <th class="descriptionbox" colspan="2"> <?php echo I18N::translate('Add individuals'); ?> </th> </tr> <tr> <td class="optionbox"> <label for="place"> <?php echo GedcomTag::getLabel('PLAC'); ?> </label> </td> <td class="optionbox" colspan="3"> <input id="place" data-autocomplete-type="PLAC" type="text" size="30" name="place"> </td> <td class="optionbox"> <label for="newpid"> <?php echo I18N::translate('Individual'); ?> </label> </td> <td class="optionbox"> <input id="newpid" class="pedigree_form" data-autocomplete-type="INDI" type="text" size="5" name="newpid"><?php
/** * An HTML form to edit block settings * * @param int $block_id */ public function configureBlock($block_id) { if (Filter::postBool('save') && Filter::checkCsrf()) { $this->setBlockSetting($block_id, 'filter', Filter::post('filter', 'indi|event|all', 'all')); $this->setBlockSetting($block_id, 'controls', Filter::postBool('controls')); $this->setBlockSetting($block_id, 'start', Filter::postBool('start')); $this->setBlockSetting($block_id, 'filter_avi', Filter::postBool('filter_avi')); $this->setBlockSetting($block_id, 'filter_bmp', Filter::postBool('filter_bmp')); $this->setBlockSetting($block_id, 'filter_gif', Filter::postBool('filter_gif')); $this->setBlockSetting($block_id, 'filter_jpeg', Filter::postBool('filter_jpeg')); $this->setBlockSetting($block_id, 'filter_mp3', Filter::postBool('filter_mp3')); $this->setBlockSetting($block_id, 'filter_ole', Filter::postBool('filter_ole')); $this->setBlockSetting($block_id, 'filter_pcx', Filter::postBool('filter_pcx')); $this->setBlockSetting($block_id, 'filter_pdf', Filter::postBool('filter_pdf')); $this->setBlockSetting($block_id, 'filter_png', Filter::postBool('filter_png')); $this->setBlockSetting($block_id, 'filter_tiff', Filter::postBool('filter_tiff')); $this->setBlockSetting($block_id, 'filter_wav', Filter::postBool('filter_wav')); $this->setBlockSetting($block_id, 'filter_audio', Filter::postBool('filter_audio')); $this->setBlockSetting($block_id, 'filter_book', Filter::postBool('filter_book')); $this->setBlockSetting($block_id, 'filter_card', Filter::postBool('filter_card')); $this->setBlockSetting($block_id, 'filter_certificate', Filter::postBool('filter_certificate')); $this->setBlockSetting($block_id, 'filter_coat', Filter::postBool('filter_coat')); $this->setBlockSetting($block_id, 'filter_document', Filter::postBool('filter_document')); $this->setBlockSetting($block_id, 'filter_electronic', Filter::postBool('filter_electronic')); $this->setBlockSetting($block_id, 'filter_fiche', Filter::postBool('filter_fiche')); $this->setBlockSetting($block_id, 'filter_film', Filter::postBool('filter_film')); $this->setBlockSetting($block_id, 'filter_magazine', Filter::postBool('filter_magazine')); $this->setBlockSetting($block_id, 'filter_manuscript', Filter::postBool('filter_manuscript')); $this->setBlockSetting($block_id, 'filter_map', Filter::postBool('filter_map')); $this->setBlockSetting($block_id, 'filter_newspaper', Filter::postBool('filter_newspaper')); $this->setBlockSetting($block_id, 'filter_other', Filter::postBool('filter_other')); $this->setBlockSetting($block_id, 'filter_painting', Filter::postBool('filter_painting')); $this->setBlockSetting($block_id, 'filter_photo', Filter::postBool('filter_photo')); $this->setBlockSetting($block_id, 'filter_tombstone', Filter::postBool('filter_tombstone')); $this->setBlockSetting($block_id, 'filter_video', Filter::postBool('filter_video')); } $filter = $this->getBlockSetting($block_id, 'filter', 'all'); $controls = $this->getBlockSetting($block_id, 'controls', '1'); $start = $this->getBlockSetting($block_id, 'start', '0') || Filter::getBool('start'); echo '<tr><td class="descriptionbox wrap width33">'; echo I18N::translate('Show only individuals, events, or all'); echo '</td><td class="optionbox">'; echo FunctionsEdit::selectEditControl('filter', array('indi' => I18N::translate('Individuals'), 'event' => I18N::translate('Facts and events'), 'all' => I18N::translate('All')), null, $filter, ''); echo '</td></tr>'; $filters = array('avi' => $this->getBlockSetting($block_id, 'filter_avi', '0'), 'bmp' => $this->getBlockSetting($block_id, 'filter_bmp', '1'), 'gif' => $this->getBlockSetting($block_id, 'filter_gif', '1'), 'jpeg' => $this->getBlockSetting($block_id, 'filter_jpeg', '1'), 'mp3' => $this->getBlockSetting($block_id, 'filter_mp3', '0'), 'ole' => $this->getBlockSetting($block_id, 'filter_ole', '1'), 'pcx' => $this->getBlockSetting($block_id, 'filter_pcx', '1'), 'pdf' => $this->getBlockSetting($block_id, 'filter_pdf', '0'), 'png' => $this->getBlockSetting($block_id, 'filter_png', '1'), 'tiff' => $this->getBlockSetting($block_id, 'filter_tiff', '1'), 'wav' => $this->getBlockSetting($block_id, 'filter_wav', '0'), 'audio' => $this->getBlockSetting($block_id, 'filter_audio', '0'), 'book' => $this->getBlockSetting($block_id, 'filter_book', '1'), 'card' => $this->getBlockSetting($block_id, 'filter_card', '1'), 'certificate' => $this->getBlockSetting($block_id, 'filter_certificate', '1'), 'coat' => $this->getBlockSetting($block_id, 'filter_coat', '1'), 'document' => $this->getBlockSetting($block_id, 'filter_document', '1'), 'electronic' => $this->getBlockSetting($block_id, 'filter_electronic', '1'), 'fiche' => $this->getBlockSetting($block_id, 'filter_fiche', '1'), 'film' => $this->getBlockSetting($block_id, 'filter_film', '1'), 'magazine' => $this->getBlockSetting($block_id, 'filter_magazine', '1'), 'manuscript' => $this->getBlockSetting($block_id, 'filter_manuscript', '1'), 'map' => $this->getBlockSetting($block_id, 'filter_map', '1'), 'newspaper' => $this->getBlockSetting($block_id, 'filter_newspaper', '1'), 'other' => $this->getBlockSetting($block_id, 'filter_other', '1'), 'painting' => $this->getBlockSetting($block_id, 'filter_painting', '1'), 'photo' => $this->getBlockSetting($block_id, 'filter_photo', '1'), 'tombstone' => $this->getBlockSetting($block_id, 'filter_tombstone', '1'), 'video' => $this->getBlockSetting($block_id, 'filter_video', '0')); ?> <tr> <td class="descriptionbox wrap width33"> <?php echo I18N::translate('Filter'); ?> </td> <td class="optionbox"> <center><b><?php echo GedcomTag::getLabel('FORM'); ?> </b></center> <table class="width100"> <tr> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_avi" <?php echo $filters['avi'] ? 'checked' : ''; ?> > avi </td> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_bmp" <?php echo $filters['bmp'] ? 'checked' : ''; ?> > bmp </label> </td> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_gif" <?php echo $filters['gif'] ? 'checked' : ''; ?> > gif </label> </td> </tr> <tr> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_jpeg" <?php echo $filters['jpeg'] ? 'checked' : ''; ?> > jpeg </label> </td> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_mp3" <?php echo $filters['mp3'] ? 'checked' : ''; ?> > mp3 </label> </td> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_ole" <?php echo $filters['ole'] ? 'checked' : ''; ?> > ole </label> </td> </tr> <tr> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_pcx" <?php echo $filters['pcx'] ? 'checked' : ''; ?> > pcx </label> </td> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_pdf" <?php echo $filters['pdf'] ? 'checked' : ''; ?> > pdf </label> </td> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_png" <?php echo $filters['png'] ? 'checked' : ''; ?> > png </label> </td> </tr> <tr> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_tiff" <?php echo $filters['tiff'] ? 'checked' : ''; ?> > tiff </label> </td> <td class="width33"> <label> <input type="checkbox" value="yes" name="filter_wav" <?php echo $filters['wav'] ? 'checked' : ''; ?> > wav </label> </td> <td class="width33"></td> <td class="width33"></td> </tr> </table> <br> <center><b><?php echo GedcomTag::getLabel('TYPE'); ?> </b></center> <table class="width100"> <tr> <?php //-- Build the list of checkboxes $i = 0; foreach (GedcomTag::getFileFormTypes() as $typeName => $typeValue) { $i++; if ($i > 3) { $i = 1; echo '</tr><tr>'; } echo '<td class="width33"><label><input type="checkbox" value="yes" name="filter_' . $typeName . '" '; echo $filters[$typeName] ? 'checked' : ''; echo '> ' . $typeValue . '</label></td>'; } ?> </tr> </table> </td> </tr> <?php echo '<tr><td class="descriptionbox wrap width33">'; echo I18N::translate('Show slide show controls'); echo '</td><td class="optionbox">'; echo FunctionsEdit::editFieldYesNo('controls', $controls); echo '</td></tr>'; echo '<tr><td class="descriptionbox wrap width33">'; echo I18N::translate('Start slide show on page load'); echo '</td><td class="optionbox">'; echo FunctionsEdit::editFieldYesNo('start', $start); echo '</td></tr>'; }
/** * An HTML form to edit block settings * * @param int $block_id */ public function configureBlock($block_id) { global $WT_TREE; if (Filter::postBool('save') && Filter::checkCsrf()) { $languages = Filter::postArray('lang'); $this->setBlockSetting($block_id, 'gedcom', Filter::post('gedcom')); $this->setBlockSetting($block_id, 'title', Filter::post('title')); $this->setBlockSetting($block_id, 'html', Filter::post('html')); $this->setBlockSetting($block_id, 'show_timestamp', Filter::postBool('show_timestamp')); $this->setBlockSetting($block_id, 'timestamp', Filter::post('timestamp')); $this->setBlockSetting($block_id, 'languages', implode(',', $languages)); } $templates = array(I18N::translate('Keyword examples') => '#getAllTagsTable#', I18N::translate('Narrative description') => I18N::translate('This family tree was last updated on #gedcomUpdated#. There are #totalSurnames# surnames in this family tree. The earliest recorded event is the #firstEventType# of #firstEventName# in #firstEventYear#. The most recent event is the #lastEventType# of #lastEventName# in #lastEventYear#.<br><br>If you have any comments or feedback please contact #contactWebmaster#.'), I18N::translate('Statistics') => '<div class="gedcom_stats"> <span style="font-weight: bold;"><a href="index.php?command=gedcom">#gedcomTitle#</a></span><br> ' . I18N::translate('This family tree was last updated on %s.', '#gedcomUpdated#') . ' <table id="keywords"> <tr> <td valign="top" class="width20"> <table cellspacing="1" cellpadding="0"> <tr> <td class="facts_label">' . I18N::translate('Individuals') . '</td> <td class="facts_value" align="right"><a href="indilist.php?surname_sublist=no">#totalIndividuals#</a></td> </tr> <tr> <td class="facts_label">' . I18N::translate('Males') . '</td> <td class="facts_value" align="right">#totalSexMales#<br>#totalSexMalesPercentage#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Females') . '</td> <td class="facts_value" align="right">#totalSexFemales#<br>#totalSexFemalesPercentage#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Total surnames') . '</td> <td class="facts_value" align="right"><a href="indilist.php?show_all=yes&surname_sublist=yes&ged=' . $WT_TREE->getNameUrl() . '">#totalSurnames#</a></td> </tr> <tr> <td class="facts_label">' . I18N::translate('Families') . '</td> <td class="facts_value" align="right"><a href="famlist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalFamilies#</a></td> </tr> <tr> <td class="facts_label">' . I18N::translate('Sources') . '</td> <td class="facts_value" align="right"><a href="sourcelist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalSources#</a></td> </tr> <tr> <td class="facts_label">' . I18N::translate('Media objects') . '</td> <td class="facts_value" align="right"><a href="medialist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalMedia#</a></td> </tr> <tr> <td class="facts_label">' . I18N::translate('Repositories') . '</td> <td class="facts_value" align="right"><a href="repolist.php?ged=' . $WT_TREE->getNameUrl() . '">#totalRepositories#</a></td> </tr> <tr> <td class="facts_label">' . I18N::translate('Total events') . '</td> <td class="facts_value" align="right">#totalEvents#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Total users') . '</td> <td class="facts_value" align="right">#totalUsers#</td> </tr> </table> </td> <td><br></td> <td valign="top"> <table cellspacing="1" cellpadding="0" border="0"> <tr> <td class="facts_label">' . I18N::translate('Earliest birth year') . '</td> <td class="facts_value" align="right">#firstBirthYear#</td> <td class="facts_value">#firstBirth#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Latest birth year') . '</td> <td class="facts_value" align="right">#lastBirthYear#</td> <td class="facts_value">#lastBirth#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Earliest death year') . '</td> <td class="facts_value" align="right">#firstDeathYear#</td> <td class="facts_value">#firstDeath#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Latest death year') . '</td> <td class="facts_value" align="right">#lastDeathYear#</td> <td class="facts_value">#lastDeath#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Individual who lived the longest') . '</td> <td class="facts_value" align="right">#longestLifeAge#</td> <td class="facts_value">#longestLife#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Average age at death') . '</td> <td class="facts_value" align="right">#averageLifespan#</td> <td class="facts_value"></td> </tr> <tr> <td class="facts_label">' . I18N::translate('Family with the most children') . '</td> <td class="facts_value" align="right">#largestFamilySize#</td> <td class="facts_value">#largestFamily#</td> </tr> <tr> <td class="facts_label">' . I18N::translate('Average number of children per family') . '</td> <td class="facts_value" align="right">#averageChildren#</td> <td class="facts_value"></td> </tr> </table> </td> </tr> </table><br> <span style="font-weight: bold;">' . I18N::translate('Most common surnames') . '</span><br> #commonSurnames# </div>'); $title = $this->getBlockSetting($block_id, 'title'); $html = $this->getBlockSetting($block_id, 'html'); $gedcom = $this->getBlockSetting($block_id, 'gedcom'); $show_timestamp = $this->getBlockSetting($block_id, 'show_timestamp', '0'); $languages = explode(',', $this->getBlockSetting($block_id, 'languages')); echo '<tr><td class="descriptionbox wrap">', GedcomTag::getLabel('TITL'), '</td><td class="optionbox"><input type="text" name="title" size="30" value="', Filter::escapeHtml($title), '"></td></tr>'; // templates echo '<tr><td class="descriptionbox wrap">', I18N::translate('Templates'), '</td><td class="optionbox wrap">'; // The CK editor needs lots of help to load/save data :-( if (Module::getModuleByName('ckeditor')) { $ckeditor_onchange = 'CKEDITOR.instances.html.setData(document.block.html.value);'; } else { $ckeditor_onchange = ''; } echo '<select name="template" onchange="document.block.html.value=document.block.template.options[document.block.template.selectedIndex].value;', $ckeditor_onchange, '">'; echo '<option value="', Filter::escapeHtml($html), '">', I18N::translate('Custom'), '</option>'; foreach ($templates as $title => $template) { echo '<option value="', Filter::escapeHtml($template), '">', $title, '</option>'; } echo '</select>'; if (!$html) { echo '<p>', I18N::translate('To assist you in getting started with this block, we have created several standard templates. When you select one of these templates, the text area will contain a copy that you can then alter to suit your site’s requirements.'), '</p>'; } echo '</td></tr>'; if (count(Tree::getAll()) > 1) { if ($gedcom == '__current__') { $sel_current = 'selected'; } else { $sel_current = ''; } if ($gedcom == '__default__') { $sel_default = 'selected'; } else { $sel_default = ''; } echo '<tr><td class="descriptionbox wrap">', I18N::translate('Family tree'), '</td><td class="optionbox">', '<select name="gedcom">', '<option value="__current__" ', $sel_current, '>', I18N::translate('Current'), '</option>', '<option value="__default__" ', $sel_default, '>', I18N::translate('Default'), '</option>'; foreach (Tree::getAll() as $tree) { if ($tree->getName() === $gedcom) { $sel = 'selected'; } else { $sel = ''; } echo '<option value="', $tree->getNameHtml(), '" ', $sel, '>', $tree->getTitleHtml(), '</option>'; } echo '</select>'; echo '</td></tr>'; } // html echo '<tr><td colspan="2" class="descriptionbox">', I18N::translate('Content'); if (!$html) { echo '<p>', I18N::translate('As well as using the toolbar to apply HTML formatting, you can insert database fields which are updated automatically. These special fields are marked with <b>#</b> characters. For example <b>#totalFamilies#</b> will be replaced with the actual number of families in the database. Advanced users may wish to apply CSS classes to their text, so that the formatting matches the currently selected theme.'), '</p>'; } echo '</td></tr><tr>', '<td colspan="2" class="optionbox">'; echo '<textarea name="html" class="html-edit" rows="10" style="width:98%;">', Filter::escapeHtml($html), '</textarea>'; echo '</td></tr>'; echo '<tr><td class="descriptionbox wrap">'; echo I18N::translate('Show the date and time of update'); echo '</td><td class="optionbox">'; echo FunctionsEdit::editFieldYesNo('show_timestamp', $show_timestamp); echo '<input type="hidden" name="timestamp" value="', WT_TIMESTAMP, '">'; echo '</td></tr>'; echo '<tr><td class="descriptionbox wrap">'; echo I18N::translate('Show this block for which languages?'); echo '</td><td class="optionbox">'; echo FunctionsEdit::editLanguageCheckboxes('lang', $languages); echo '</td></tr>'; }
FunctionsEdit::addSimpleTag($subLevel . ' ' . $fact . ' ' . $event); } } } if ($sourceSOUR !== '') { // Get rid of all saved Source data FunctionsEdit::addSimpleTag($sourceLevel . ' SOUR ' . $sourceSOUR); FunctionsEdit::addSimpleTag($sourceLevel + 1 . ' PAGE ' . $sourcePAGE); FunctionsEdit::addSimpleTag($sourceLevel + 2 . ' TEXT ' . $sourceTEXT); FunctionsEdit::addSimpleTag($sourceLevel + 2 . ' DATE ' . $sourceDATE, '', GedcomTag::getLabel('DATA:DATE')); FunctionsEdit::addSimpleTag($sourceLevel + 1 . ' QUAY ' . $sourceQUAY); } } if (Auth::isAdmin() && $action === 'update') { echo '<tr><td class="descriptionbox wrap width25">'; echo GedcomTag::getLabel('CHAN'), '</td><td class="optionbox wrap">'; if ($NO_UPDATE_CHAN) { echo '<input type="checkbox" checked name="preserve_last_changed">'; } else { echo '<input type="checkbox" name="preserve_last_changed">'; } echo I18N::translate('Keep the existing “last change” information'), '<br>'; echo '</td></tr>'; } echo '</table>'; FunctionsEdit::printAddLayer('SOUR', 1); FunctionsEdit::printAddLayer('NOTE', 1); FunctionsEdit::printAddLayer('SHARED_NOTE', 1); FunctionsEdit::printAddLayer('RESN', 1); ?> <p id="save-cancel">
type="text" value="<?php echo Filter::escapeHtml($WT_TREE->getPreference('GEONAMES_ACCOUNT')); ?> " > <p class="small text-muted"> <?php echo I18N::translate('The website www.geonames.org provides a large database of place names. This can be searched when entering new places. To use this feature, you must register for a free account at www.geonames.org and provide the username.'); ?> </p> </div> </div> <h3><?php echo GedcomTag::getLabel('TEXT'); ?> </h3> <!-- FORMAT_TEXT --> <fieldset class="form-group"> <legend class="control-label col-sm-3"> <?php echo I18N::translate('Format text and notes'); ?> </legend> <div class="col-sm-9"> <?php echo FunctionsEdit::radioButtons('FORMAT_TEXT', $formats, $WT_TREE->getPreference('FORMAT_TEXT'), 'class="radio-inline"'); ?> <p class="small text-muted">
/** * Print a row for the media tab on the individual page. * * @param Fact $fact * @param int $level */ public static function printMainMedia(Fact $fact, $level) { $factrec = $fact->getGedcom(); $parent = $fact->getParent(); if ($fact->isPendingAddition()) { $styleadd = 'new'; $can_edit = $level == 1 && $fact->canEdit(); } elseif ($fact->isPendingDeletion()) { $styleadd = 'old'; $can_edit = false; } else { $styleadd = ''; $can_edit = $level == 1 && $fact->canEdit(); } // -- find source for each fact preg_match_all('/(?:^|\\n)' . $level . ' OBJE @(.*)@/', $factrec, $matches); foreach ($matches[1] as $xref) { $media = Media::getInstance($xref, $fact->getParent()->getTree()); // Allow access to "1 OBJE @non_existent_source@", so it can be corrected/deleted if (!$media || $media->canShow()) { if ($level > 1) { echo '<tr class="row_obje2">'; } else { echo '<tr>'; } echo '<td class="descriptionbox'; if ($level > 1) { echo ' rela'; } echo ' ', $styleadd, ' width20">'; preg_match("/^\\d (\\w*)/", $factrec, $factname); $factlines = explode("\n", $factrec); // 1 BIRT Y\n2 SOUR ... $factwords = explode(" ", $factlines[0]); // 1 BIRT Y $factname = $factwords[1]; // BIRT if ($factname == 'EVEN' || $factname == 'FACT') { // Add ' EVEN' to provide sensible output for an event with an empty TYPE record $ct = preg_match("/2 TYPE (.*)/", $factrec, $ematch); if ($ct > 0) { $factname = $ematch[1]; echo $factname; } else { echo GedcomTag::getLabel($factname, $parent); } } elseif ($can_edit) { echo '<a onclick="window.open(\'addmedia.php?action=editmedia&pid=', $media->getXref(), '\', \'_blank\', edit_window_specs); return false;" href="#" title="', I18N::translate('Edit'), '">'; echo GedcomTag::getLabel($factname, $parent), '</a>'; echo '<div class="editfacts">'; echo '<div class="editlink"><a class="editicon" onclick="window.open(\'addmedia.php?action=editmedia&pid=', $media->getXref(), '\', \'_blank\', edit_window_specs); return false;" href="#" title="', I18N::translate('Edit'), '"><span class="link_text">', I18N::translate('Edit'), '</span></a></div>'; echo '<div class="copylink"><a class="copyicon" href="#" onclick="jQuery.post(\'action.php\',{action:\'copy-fact\', type:\'\', factgedcom:\'' . rawurlencode($factrec) . '\'},function(){location.reload();})" title="' . I18N::translate('Copy') . '"><span class="link_text">' . I18N::translate('Copy') . '</span></a></div>'; echo '<div class="deletelink"><a class="deleteicon" onclick="return delete_fact(\'', I18N::translate('Are you sure you want to delete this fact?'), '\', \'', $parent->getXref(), '\', \'', $fact->getFactId(), '\');" href="#" title="', I18N::translate('Delete'), '"><span class="link_text">', I18N::translate('Delete'), '</span></a></div>'; echo '</div>'; } else { echo GedcomTag::getLabel($factname, $parent); } echo '</td>'; echo '<td class="optionbox ', $styleadd, ' wrap">'; if ($media) { echo '<span class="field">'; echo $media->displayImage(); echo '<a href="' . $media->getHtmlUrl() . '">'; echo '<em>'; foreach ($media->getAllNames() as $name) { if ($name['type'] != 'TITL') { echo '<br>'; } echo $name['full']; } echo '</em>'; echo '</a>'; echo '</span>'; echo GedcomTag::getLabelValue('FORM', $media->mimeType()); $imgsize = $media->getImageAttributes('main'); if (!empty($imgsize['WxH'])) { echo GedcomTag::getLabelValue('__IMAGE_SIZE__', $imgsize['WxH']); } if ($media->getFilesizeraw() > 0) { echo GedcomTag::getLabelValue('__FILE_SIZE__', $media->getFilesize()); } $mediatype = $media->getMediaType(); if ($mediatype) { echo GedcomTag::getLabelValue('TYPE', GedcomTag::getFileFormTypeValue($mediatype)); } switch ($media->isPrimary()) { case 'Y': echo GedcomTag::getLabelValue('_PRIM', I18N::translate('yes')); break; case 'N': echo GedcomTag::getLabelValue('_PRIM', I18N::translate('no')); break; } echo FunctionsPrint::printFactNotes($media->getGedcom(), 1); echo self::printFactSources($media->getGedcom(), 1); } else { echo $xref; } echo '</td></tr>'; } } }
/** * Format a table of events * * @param GedcomRecord[] $records * @param string $sort * @param bool $show_user * * @return string */ private function changesTable($records, $sort, $show_user) { global $controller; $table_id = 'table-chan-' . Uuid::uuid4(); // lists requires a unique ID in case there are multiple lists per page switch ($sort) { case 'name': default: $aaSorting = "[2,'asc'], [4,'desc']"; break; case 'date_asc': $aaSorting = "[4,'asc'], [2,'asc']"; break; case 'date_desc': $aaSorting = "[4,'desc'], [2,'asc']"; break; } $html = ''; $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addInlineJavascript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery("#' . $table_id . '").dataTable({ dom: \'t\', paging: false, autoWidth:false, lengthChange: false, filter: false, ' . I18N::datatablesI18N() . ', jQueryUI: true, sorting: [' . $aaSorting . '], columns: [ /* 0-Type */ { sortable: false, class: "center" }, /* 1-Record */ { dataSort: 2 }, /* 2-SORTNAME */ { type: "unicode" }, /* 3-Change */ { dataSort: 4 }, /* 4-DATE */ null ' . ($show_user ? ',/* 5-By */ null' : '') . ' ] }); '); $html .= '<table id="' . $table_id . '" class="width100">'; $html .= '<thead><tr>'; $html .= '<th></th>'; $html .= '<th>' . I18N::translate('Record') . '</th>'; $html .= '<th hidden>SORTNAME</th>'; $html .= '<th>' . GedcomTag::getLabel('CHAN') . '</th>'; $html .= '<th hidden>DATE</th>'; if ($show_user) { $html .= '<th>' . GedcomTag::getLabel('_WT_USER') . '</th>'; } $html .= '</tr></thead><tbody>'; foreach ($records as $record) { $html .= '<tr><td>'; switch ($record::RECORD_TYPE) { case 'INDI': $icon = $record->getSexImage('small'); break; case 'FAM': $icon = '<i class="icon-button_family"></i>'; break; case 'OBJE': $icon = '<i class="icon-button_media"></i>'; break; case 'NOTE': $icon = '<i class="icon-button_note"></i>'; break; case 'SOUR': $icon = '<i class="icon-button_source"></i>'; break; case 'REPO': $icon = '<i class="icon-button_repository"></i>'; break; default: $icon = ' '; break; } $html .= '<a href="' . $record->getHtmlUrl() . '">' . $icon . '</a>'; $html .= '</td>'; $name = $record->getFullName(); $html .= '<td class="wrap">'; $html .= '<a href="' . $record->getHtmlUrl() . '">' . $name . '</a>'; if ($record instanceof Individual) { $addname = $record->getAddName(); if ($addname) { $html .= '<div class="indent"><a href="' . $record->getHtmlUrl() . '">' . $addname . '</a></div>'; } } $html .= '</td>'; $html .= '<td hidden>' . $record->getSortName() . '</td>'; $html .= '<td class="wrap">' . $record->lastChangeTimestamp() . '</td>'; $html .= '<td hidden>' . $record->lastChangeTimestamp(true) . '</td>'; if ($show_user) { $html .= '<td class="wrap">' . Filter::escapeHtml($record->lastChangeUser()) . '</td>'; } $html .= '</tr>'; } $html .= '</tbody></table>'; return $html; }
/** * Populate the timeline * * @return int */ public function fillTimeline() { $rows = array(); $maxY = self::CHART_TOP; //base case if (!$this->people) { return $maxY; } foreach ($this->people as $person) { $bdate = $this->getCalendarDate($person->getEstimatedBirthDate()->minimumJulianDay()); $ddate = $this->getCalendarDate($person->getEstimatedDeathDate()->maximumJulianDay()); $birthYear = $bdate->y; $age = min($ddate->y, $this->currentYear) - $birthYear; // truncate the bar at the current year $width = max(9, $age * self::PIXELS_PER_YEAR); // min width is width of sex icon $startPos = ($birthYear - $this->timelineMinYear) * self::PIXELS_PER_YEAR; //-- calculate a good Y top value $Y = self::CHART_TOP; $ready = false; while (!$ready) { if (!isset($rows[$Y])) { $ready = true; $rows[$Y]['x1'] = $startPos; $rows[$Y]['x2'] = $startPos + $width; } else { if ($rows[$Y]['x1'] > $startPos + $width) { $ready = true; $rows[$Y]['x1'] = $startPos; } elseif ($rows[$Y]['x2'] < $startPos) { $ready = true; $rows[$Y]['x2'] = $startPos + $width; } else { //move down a line $Y += self::BAR_SPACING; } } } $facts = $person->getFacts(); foreach ($person->getSpouseFamilies() as $family) { foreach ($family->getFacts() as $fact) { $facts[] = $fact; } } Functions::sortFacts($facts); $that = $this; // PHP5.3 cannot access $this inside a closure $acceptedFacts = array_filter($facts, function (Fact $fact) use($that) { return in_array($fact->getTag(), $that->facts) && $fact->getDate()->isOK() || ($that->place_obj || $that->startDate) && $that->checkFact($fact); }); $eventList = array(); foreach ($acceptedFacts as $fact) { $tag = $fact->getTag(); //-- if the fact is a generic EVENt then get the qualifying TYPE if ($tag == "EVEN") { $tag = $fact->getAttribute('TYPE'); } $eventList[] = array('label' => GedcomTag::getLabel($tag), 'date' => $fact->getDate()->display(), 'place' => $fact->getPlace()->getFullName()); } $direction = I18N::direction() === 'ltr' ? 'left' : 'right'; $lifespan = ' ' . $person->getLifeSpan(); // put the space here so its included in the length calcs $sex = $person->getSex(); $popupClass = strtr($sex, array('M' => '', 'U' => 'NN')); $color = $sex === 'U' ? '' : sprintf("background-color: %s", $this->colors[$sex]->getNextColor()); // following lines are a nasty method of approximating // the width of a string in pixels from the character count $name_length = mb_strlen(strip_tags($person->getFullName())) * 6.5; $short_name_length = mb_strlen(strip_tags($person->getShortName())) * 6.5; $lifespan_length = mb_strlen(strip_tags($lifespan)) * 6.5; if ($width > $name_length + $lifespan_length) { $printName = $person->getFullName(); $abbrLifespan = $lifespan; } elseif ($width > $name_length) { $printName = $person->getFullName(); $abbrLifespan = '…'; } elseif ($width > $short_name_length) { $printName = $person->getShortName(); $abbrLifespan = ''; } else { $printName = ''; $abbrLifespan = ''; } // Bar framework printf(' <div class="person_box%s" style="top:%spx; %s:%spx; width:%spx; %s"> <div class="itr">%s %s %s <div class="popup person_box%s"> <div> <a href="%s">%s%s</a> </div>', $popupClass, $Y, $direction, $startPos, $width, $color, $person->getSexImage(), $printName, $abbrLifespan, $popupClass, $person->getHtmlUrl(), $person->getFullName(), $lifespan); // Add events to popup foreach ($eventList as $event) { printf("<div>%s: %s %s</div>", $event['label'], $event['date'], $event['place']); } echo '</div>' . '</div>' . '</div>'; // class=$popupclass $maxY = max($maxY, $Y); } return $maxY; }
/** * Get the label. * * @param string $tag * * @return string */ public function getLabel($tag) { return GedcomTag::getLabel(preg_replace('/:(SDX|BEGINS|EXACT|CONTAINS)$/', '', $tag)); }
/** * Places administration. */ private function adminPlaces() { global $WT_TREE; $action = Filter::get('action'); $parent = Filter::get('parent'); $inactive = Filter::getBool('inactive'); $deleteRecord = Filter::get('deleteRecord'); if (!isset($parent)) { $parent = 0; } $controller = new PageController(); $controller->restrictAccess(Auth::isAdmin()); if ($action == 'ExportFile' && Auth::isAdmin()) { $tmp = $this->placeIdToHierarchy($parent); $maxLevel = $this->getHighestLevel(); if ($maxLevel > 8) { $maxLevel = 8; } $tmp[0] = 'places'; $outputFileName = preg_replace('/[:;\\/\\\\(\\)\\{\\}\\[\\] $]/', '_', implode('-', $tmp)) . '.csv'; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $outputFileName . '"'); echo '"', I18N::translate('Level'), '";"', I18N::translate('Country'), '";'; if ($maxLevel > 0) { echo '"', I18N::translate('State'), '";'; } if ($maxLevel > 1) { echo '"', I18N::translate('County'), '";'; } if ($maxLevel > 2) { echo '"', I18N::translate('City'), '";'; } if ($maxLevel > 3) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 4) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 5) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 6) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 7) { echo '"', I18N::translate('Place'), '";'; } echo '"', I18N::translate('Longitude'), '";"', I18N::translate('Latitude'), '";'; echo '"', I18N::translate('Zoom level'), '";"', I18N::translate('Icon'), '";', WT_EOL; $this->outputLevel($parent); exit; } $controller->setPageTitle(I18N::translate('Google Maps™'))->pageHeader(); ?> <ol class="breadcrumb small"> <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?> </a></li> <li><a href="admin_modules.php"><?php echo I18N::translate('Module administration'); ?> </a></li> <li class="active"><?php echo $controller->getPageTitle(); ?> </li> </ol> <ul class="nav nav-tabs nav-justified" role="tablist"> <li role="presentation"> <a href="?mod=googlemap&mod_action=admin_config" role="tab"> <?php echo I18N::translate('Google Maps™ preferences'); ?> </a> </li> <li role="presentation" class="active"> <a href="#"> <?php echo I18N::translate('Geographic data'); ?> </a> </li> <li role="presentation"> <a href="?mod=googlemap&mod_action=admin_placecheck"> <?php echo I18N::translate('Place check'); ?> </a> </li> </ul> <h2><?php echo I18N::translate('Geographic data'); ?> </h2> <?php if ($action == 'ImportGedcom') { $placelist = array(); $j = 0; $gedcom_records = Database::prepare("SELECT i_gedcom FROM `##individuals` WHERE i_file=? UNION ALL SELECT f_gedcom FROM `##families` WHERE f_file=?")->execute(array($WT_TREE->getTreeId(), $WT_TREE->getTreeId()))->fetchOneColumn(); foreach ($gedcom_records as $gedrec) { $i = 1; $placerec = Functions::getSubRecord(2, '2 PLAC', $gedrec, $i); while (!empty($placerec)) { if (preg_match("/2 PLAC (.+)/", $placerec, $match)) { $placelist[$j] = array(); $placelist[$j]['place'] = trim($match[1]); if (preg_match("/4 LATI (.*)/", $placerec, $match)) { $placelist[$j]['lati'] = trim($match[1]); if ($placelist[$j]['lati'][0] != 'N' && $placelist[$j]['lati'][0] != 'S') { if ($placelist[$j]['lati'] < 0) { $placelist[$j]['lati'][0] = 'S'; } else { $placelist[$j]['lati'] = 'N' . $placelist[$j]['lati']; } } } else { $placelist[$j]['lati'] = null; } if (preg_match("/4 LONG (.*)/", $placerec, $match)) { $placelist[$j]['long'] = trim($match[1]); if ($placelist[$j]['long'][0] != 'E' && $placelist[$j]['long'][0] != 'W') { if ($placelist[$j]['long'] < 0) { $placelist[$j]['long'][0] = 'W'; } else { $placelist[$j]['long'] = 'E' . $placelist[$j]['long']; } } } else { $placelist[$j]['long'] = null; } $j = $j + 1; } $i = $i + 1; $placerec = Functions::getSubRecord(2, '2 PLAC', $gedrec, $i); } } asort($placelist); $prevPlace = ''; $prevLati = ''; $prevLong = ''; $placelistUniq = array(); $j = 0; foreach ($placelist as $k => $place) { if ($place['place'] != $prevPlace) { $placelistUniq[$j] = array(); $placelistUniq[$j]['place'] = $place['place']; $placelistUniq[$j]['lati'] = $place['lati']; $placelistUniq[$j]['long'] = $place['long']; $j = $j + 1; } elseif ($place['place'] == $prevPlace && ($place['lati'] != $prevLati || $place['long'] != $prevLong)) { if ($placelistUniq[$j - 1]['lati'] == 0 || $placelistUniq[$j - 1]['long'] == 0) { $placelistUniq[$j - 1]['lati'] = $place['lati']; $placelistUniq[$j - 1]['long'] = $place['long']; } elseif ($place['lati'] != '0' || $place['long'] != '0') { echo 'Difference: previous value = ', $prevPlace, ', ', $prevLati, ', ', $prevLong, ' current = ', $place['place'], ', ', $place['lati'], ', ', $place['long'], '<br>'; } } $prevPlace = $place['place']; $prevLati = $place['lati']; $prevLong = $place['long']; } $highestIndex = $this->getHighestIndex(); $default_zoom_level = array(4, 7, 10, 12); foreach ($placelistUniq as $k => $place) { $parent = preg_split('/ *, */', $place['place']); $parent = array_reverse($parent); $parent_id = 0; for ($i = 0; $i < count($parent); $i++) { if (!isset($default_zoom_level[$i])) { $default_zoom_level[$i] = $default_zoom_level[$i - 1]; } $escparent = $parent[$i]; if ($escparent == '') { $escparent = 'Unknown'; } $row = Database::prepare("SELECT pl_id, pl_long, pl_lati, pl_zoom FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ?")->execute(array($i, $parent_id, $escparent))->fetchOneRow(); if ($i < count($parent) - 1) { // Create higher-level places, if necessary if (empty($row)) { $highestIndex++; Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_zoom) VALUES (?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $default_zoom_level[$i])); echo Filter::escapeHtml($escparent), '<br>'; $parent_id = $highestIndex; } else { $parent_id = $row->pl_id; } } else { // Create lowest-level place, if necessary if (empty($row->pl_id)) { $highestIndex++; Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_long, pl_lati, pl_zoom) VALUES (?, ?, ?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $place['long'], $place['lati'], $default_zoom_level[$i])); echo Filter::escapeHtml($escparent), '<br>'; } else { if (empty($row->pl_long) && empty($row->pl_lati) && $place['lati'] != '0' && $place['long'] != '0') { Database::prepare("UPDATE `##placelocation` SET pl_lati=?, pl_long=? WHERE pl_id=?")->execute(array($place['lati'], $place['long'], $row->pl_id)); echo Filter::escapeHtml($escparent), '<br>'; } } } } } $parent = 0; } if ($action === 'ImportFile') { $placefiles = $this->findFiles(WT_MODULES_DIR . 'googlemap/extra'); sort($placefiles); ?> <form class="form-horizontal" method="post" enctype="multipart/form-data" id="importfile" name="importfile" action="module.php?mod=googlemap&mod_action=admin_places&action=ImportFile2"> <!-- PLACES FILE --> <div class="form-group"> <label class="control-label col-sm-4" for="placesfile"> <?php echo I18N::translate('File containing places (CSV)'); ?> </label> <div class="col-sm-8"> <div class="btn btn-default"> <input id="placesfile" type="file" name="placesfile"> </div> </div> </div> <!-- LOCAL FILE --> <?php if (count($placefiles) > 0) { ?> <div class="form-group"> <label class="control-label col-sm-4" for="localfile"> <?php echo I18N::translate('Server file containing places (CSV)'); ?> </label> <div class="col-sm-8"> <div class="input-group"> <span class="input-group-addon"> <?php echo WT_MODULES_DIR . 'googlemap/extra/'; ?> </span> <?php foreach ($placefiles as $p => $placefile) { unset($placefiles[$p]); $p = Filter::escapeHtml($placefile); if (substr($placefile, 0, 1) == "/") { $placefiles[$p] = substr($placefile, 1); } else { $placefiles[$p] = $placefile; } } echo FunctionsEdit::selectEditControl('localfile', $placefiles, '', '', 'class="form-control"'); ?> </div> </div> </div> <?php } ?> <!-- CLEAR DATABASE --> <fieldset class="form-group"> <legend class="control-label col-sm-4"> <?php echo I18N::translate('Delete all existing geographic data before importing the file.'); ?> </legend> <div class="col-sm-8"> <?php echo FunctionsEdit::editFieldYesNo('cleardatabase', 0, 'class="radio-inline"'); ?> </div> </fieldset> <!-- UPDATE ONLY --> <fieldset class="form-group"> <legend class="control-label col-sm-4"> <?php echo I18N::translate('Do not create new locations, just import coordinates for existing locations.'); ?> </legend> <div class="col-sm-8"> <?php echo FunctionsEdit::editFieldYesNo('updateonly', 0, 'class="radio-inline"'); ?> </div> </fieldset> <!-- OVERWRITE DATA --> <fieldset class="form-group"> <legend class="control-label col-sm-4"> <?php echo I18N::translate('Overwrite existing coordinates.'); ?> </legend> <div class="col-sm-8"> <?php echo FunctionsEdit::editFieldYesNo('overwritedata', 0, 'class="radio-inline"'); ?> </div> </fieldset> <!-- SAVE BUTTON --> <div class="form-group"> <div class="col-sm-offset-4 col-sm-8"> <button type="submit" class="btn btn-primary"> <i class="fa fa-check"></i> <?php echo I18N::translate('Continue adding'); ?> </button> </div> </div> </form> <?php exit; } if ($action === 'ImportFile2') { $country_names = array(); $stats = new Stats($WT_TREE); foreach ($stats->iso3166() as $key => $value) { $country_names[$key] = I18N::translate($key); } if (Filter::postBool('cleardatabase')) { Database::exec("DELETE FROM `##placelocation` WHERE 1=1"); } if (!empty($_FILES['placesfile']['tmp_name'])) { $lines = file($_FILES['placesfile']['tmp_name']); } elseif (!empty($_REQUEST['localfile'])) { $lines = file(WT_MODULES_DIR . 'googlemap/extra' . $_REQUEST['localfile']); } // Strip BYTE-ORDER-MARK, if present if (!empty($lines[0]) && substr($lines[0], 0, 3) === WT_UTF8_BOM) { $lines[0] = substr($lines[0], 3); } asort($lines); $highestIndex = $this->getHighestIndex(); $placelist = array(); $j = 0; $maxLevel = 0; foreach ($lines as $p => $placerec) { $fieldrec = explode(';', $placerec); if ($fieldrec[0] > $maxLevel) { $maxLevel = $fieldrec[0]; } } $fields = count($fieldrec); $set_icon = true; if (!is_dir(WT_MODULES_DIR . 'googlemap/places/flags/')) { $set_icon = false; } foreach ($lines as $p => $placerec) { $fieldrec = explode(';', $placerec); if (is_numeric($fieldrec[0]) && $fieldrec[0] <= $maxLevel) { $placelist[$j] = array(); $placelist[$j]['place'] = ''; for ($ii = $fields - 4; $ii > 1; $ii--) { if ($fieldrec[0] > $ii - 2) { $placelist[$j]['place'] .= $fieldrec[$ii] . ','; } } foreach ($country_names as $countrycode => $countryname) { if ($countrycode == strtoupper($fieldrec[1])) { $fieldrec[1] = $countryname; break; } } $placelist[$j]['place'] .= $fieldrec[1]; $placelist[$j]['long'] = $fieldrec[$fields - 4]; $placelist[$j]['lati'] = $fieldrec[$fields - 3]; $placelist[$j]['zoom'] = $fieldrec[$fields - 2]; if ($set_icon) { $placelist[$j]['icon'] = trim($fieldrec[$fields - 1]); } else { $placelist[$j]['icon'] = ''; } $j = $j + 1; } } $prevPlace = ''; $prevLati = ''; $prevLong = ''; $placelistUniq = array(); $j = 0; foreach ($placelist as $k => $place) { if ($place['place'] != $prevPlace) { $placelistUniq[$j] = array(); $placelistUniq[$j]['place'] = $place['place']; $placelistUniq[$j]['lati'] = $place['lati']; $placelistUniq[$j]['long'] = $place['long']; $placelistUniq[$j]['zoom'] = $place['zoom']; $placelistUniq[$j]['icon'] = $place['icon']; $j = $j + 1; } elseif ($place['place'] == $prevPlace && ($place['lati'] != $prevLati || $place['long'] != $prevLong)) { if ($placelistUniq[$j - 1]['lati'] == 0 || $placelistUniq[$j - 1]['long'] == 0) { $placelistUniq[$j - 1]['lati'] = $place['lati']; $placelistUniq[$j - 1]['long'] = $place['long']; $placelistUniq[$j - 1]['zoom'] = $place['zoom']; $placelistUniq[$j - 1]['icon'] = $place['icon']; } elseif ($place['lati'] != '0' || $place['long'] != '0') { echo 'Difference: previous value = ', $prevPlace, ', ', $prevLati, ', ', $prevLong, ' current = ', $place['place'], ', ', $place['lati'], ', ', $place['long'], '<br>'; } } $prevPlace = $place['place']; $prevLati = $place['lati']; $prevLong = $place['long']; } $default_zoom_level = array(); $default_zoom_level[0] = 4; $default_zoom_level[1] = 7; $default_zoom_level[2] = 10; $default_zoom_level[3] = 12; foreach ($placelistUniq as $k => $place) { $parent = explode(',', $place['place']); $parent = array_reverse($parent); $parent_id = 0; for ($i = 0; $i < count($parent); $i++) { $escparent = $parent[$i]; if ($escparent == '') { $escparent = 'Unknown'; } $row = Database::prepare("SELECT pl_id, pl_long, pl_lati, pl_zoom, pl_icon FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ? ORDER BY pl_place")->execute(array($i, $parent_id, $escparent))->fetchOneRow(); if (empty($row)) { // this name does not yet exist: create entry if (!Filter::postBool('updateonly')) { $highestIndex = $highestIndex + 1; if ($i + 1 == count($parent)) { $zoomlevel = $place['zoom']; } elseif (isset($default_zoom_level[$i])) { $zoomlevel = $default_zoom_level[$i]; } else { $zoomlevel = $this->getSetting('GM_MAX_ZOOM'); } if ($place['lati'] == '0' || $place['long'] == '0' || $i + 1 < count($parent)) { Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_zoom, pl_icon) VALUES (?, ?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $zoomlevel, $place['icon'])); } else { //delete leading zero $pl_lati = str_replace(array('N', 'S', ','), array('', '-', '.'), $place['lati']); $pl_long = str_replace(array('E', 'W', ','), array('', '-', '.'), $place['long']); if ($pl_lati >= 0) { $place['lati'] = 'N' . abs($pl_lati); } elseif ($pl_lati < 0) { $place['lati'] = 'S' . abs($pl_lati); } if ($pl_long >= 0) { $place['long'] = 'E' . abs($pl_long); } elseif ($pl_long < 0) { $place['long'] = 'W' . abs($pl_long); } Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_long, pl_lati, pl_zoom, pl_icon) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $place['long'], $place['lati'], $zoomlevel, $place['icon'])); } $parent_id = $highestIndex; } } else { $parent_id = $row->pl_id; if (Filter::postBool('overwritedata') && $i + 1 == count($parent)) { Database::prepare("UPDATE `##placelocation` SET pl_lati = ?, pl_long = ?, pl_zoom = ?, pl_icon = ? WHERE pl_id = ?")->execute(array($place['lati'], $place['long'], $place['zoom'], $place['icon'], $parent_id)); } else { // Update only if existing data is missing if (!$row->pl_long && !$row->pl_lati) { Database::prepare("UPDATE `##placelocation` SET pl_lati = ?, pl_long = ? WHERE pl_id = ?")->execute(array($place['lati'], $place['long'], $parent_id)); } if (!$row->pl_icon && $place['icon']) { Database::prepare("UPDATE `##placelocation` SET pl_icon = ? WHERE pl_id = ?")->execute(array($place['icon'], $parent_id)); } } } } } $parent = 0; } if ($action == 'DeleteRecord') { $exists = Database::prepare("SELECT 1 FROM `##placelocation` WHERE pl_parent_id=?")->execute(array($deleteRecord))->fetchOne(); if (!$exists) { Database::prepare("DELETE FROM `##placelocation` WHERE pl_id=?")->execute(array($deleteRecord)); } else { echo '<table class="facts_table"><tr><td>', I18N::translate('Location not removed: this location contains sub-locations'), '</td></tr></table>'; } } ?> <script> function updateList(inactive) { window.location.href='<?php if (strstr($_SERVER['REQUEST_URI'], '&inactive', true)) { $uri = strstr($_SERVER['REQUEST_URI'], '&inactive', true); } else { $uri = $_SERVER['REQUEST_URI']; } echo $uri, '&inactive='; ?> '+inactive; } function edit_place_location(placeid) { window.open('module.php?mod=googlemap&mod_action=places_edit&action=update&placeid='+placeid, '_blank', gmap_window_specs); return false; } function add_place_location(placeid) { window.open('module.php?mod=googlemap&mod_action=places_edit&action=add&placeid='+placeid, '_blank', gmap_window_specs); return false; } function delete_place(placeid) { var answer=confirm('<?php echo I18N::translate('Remove this location?'); ?> '); if (answer == true) { window.location = '<?php echo Functions::getQueryUrl(array('action' => 'DeleteRecord')); ?> &action=DeleteRecord&deleteRecord=' + placeid; } } </script> <p id="gm_breadcrumb"> <?php $where_am_i = $this->placeIdToHierarchy($parent); foreach (array_reverse($where_am_i, true) as $id => $place) { if ($id == $parent) { if ($place != 'Unknown') { echo Filter::escapeHtml($place); } else { echo I18N::translate('unknown'); } } else { echo '<a href="module.php?mod=googlemap&mod_action=admin_places&parent=', $id, '&inactive=', $inactive, '">'; if ($place != 'Unknown') { echo Filter::escapeHtml($place), '</a>'; } else { echo I18N::translate('unknown'), '</a>'; } } echo ' - '; } ?> <a href="module.php?mod=googlemap&mod_action=admin_places&parent=0&inactive=', $inactive, '"><?php echo I18N::translate('Top level'); ?> </a> </p> <form class="form-inline" name="active" method="post" action="module.php?mod=googlemap&mod_action=admin_places&parent=', $parent, '&inactive=', $inactive, '"> <div class="checkbox"> <label for="inactive"> <?php echo FunctionsEdit::checkbox('inactive', $inactive, 'onclick="updateList(this.checked)"'); ?> <?php echo I18N::translate('Show inactive places'); ?> </label> </div> <p class="small text-muted"> <?php echo I18N::translate('By default, the list shows only those places which can be found in your family trees. You may have details for other places, such as those imported in bulk from an external file. Selecting this option will show all places, including ones that are not currently used.'); ?> <?php echo I18N::translate('If you have a large number of inactive places, it can be slow to generate the list.'); ?> </p> </form> <?php $placelist = $this->getPlaceListLocation($parent, $inactive); echo '<div class="gm_plac_edit">'; echo '<table class="table table-bordered table-condensed table-hover"><tr>'; echo '<th>', GedcomTag::getLabel('PLAC'), '</th>'; echo '<th>', GedcomTag::getLabel('LATI'), '</th>'; echo '<th>', GedcomTag::getLabel('LONG'), '</th>'; echo '<th>', I18N::translate('Zoom level'), '</th>'; echo '<th>', I18N::translate('Icon'), '</th>'; echo '<th>'; echo I18N::translate('Edit'), '</th><th>', I18N::translate('Delete'), '</th></tr>'; if (count($placelist) == 0) { echo '<tr><td colspan="7">', I18N::translate('No places found'), '</td></tr>'; } foreach ($placelist as $place) { echo '<tr><td><a href="module.php?mod=googlemap&mod_action=admin_places&parent=', $place['place_id'], '&inactive=', $inactive, '">'; if ($place['place'] != 'Unknown') { echo Filter::escapeHtml($place['place']), '</a></td>'; } else { echo I18N::translate('unknown'), '</a></td>'; } echo '<td>', $place['lati'], '</td>'; echo '<td>', $place['long'], '</td>'; echo '<td>', $place['zoom'], '</td>'; echo '<td>'; if ($place['icon']) { echo '<img src="', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/', $place['icon'], '" width="25" height="15">'; } else { if ($place['lati'] || $place['long']) { echo '<img src="', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/images/mm_20_red.png">'; } else { echo '<img src="', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/images/mm_20_yellow.png">'; } } echo '</td>'; echo '<td class="narrow"><a href="#" onclick="edit_place_location(', $place['place_id'], ');return false;" class="icon-edit" title="', I18N::translate('Edit'), '"></a></td>'; $noRows = Database::prepare("SELECT COUNT(pl_id) FROM `##placelocation` WHERE pl_parent_id=?")->execute(array($place['place_id']))->fetchOne(); if ($noRows == 0) { ?> <td><a href="#" onclick="delete_place(<?php echo $place['place_id']; ?> );return false;" class="icon-delete" title="<?php echo I18N::translate('Remove'); ?> "></a></td> <?php } else { ?> <td><i class="icon-delete-grey"></i></td> <?php } ?> </tr> <?php } ?> </table> </div> <hr> <form class="form-horizontal" action="?" onsubmit="add_place_location(this.parent_id.options[this.parent_id.selectedIndex].value); return false;"> <div class="form-group"> <label class="form-control-static col-sm-4" for="parent_id"> <?php echo I18N::translate('Add a new geographic location'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <?php echo FunctionsEdit::selectEditControl('parent_id', $where_am_i, I18N::translate('Top level'), $parent, 'class="form-control"'); ?> </div> <button type="submit" class="btn btn-default"> <i class="fa fa-plus"></i> <?php echo I18N::translate('Add'); ?> </button> </div> </div> </form> <form class="form-horizontal" action="module.php" method="get"> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="admin_places"> <input type="hidden" name="action" value="ImportGedcom"> <div class="form-group"> <label class="form-control-static col-sm-4" for="ged"> <?php echo I18N::translate('Import all places from a family tree'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <?php echo FunctionsEdit::selectEditControl('ged', Tree::getNameList(), null, $WT_TREE->getName(), 'class="form-control"'); ?> </div> <button type="submit" class="btn btn-default"> <i class="fa fa-upload"></i> <?php echo I18N::translate('Import'); ?> </button> </div> </div> </form> <form class="form-horizontal" action="module.php" method="get"> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="admin_places"> <input type="hidden" name="action" value="ImportFile"> <div class="form-group"> <label class="form-control-static col-sm-4"> <?php echo I18N::translate('Upload geographic data'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <button type="submit" class="btn btn-default"> <i class="fa fa-upload"></i> <?php echo I18N::translate('Upload'); ?> </button> </div> </div> </div> </form> <form class="form-horizontal" action="module.php" method="get"> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="admin_places"> <input type="hidden" name="action" value="ExportFile"> <div class="form-group"> <label class="form-control-static col-sm-4"> <?php echo I18N::translate('Download geographic data'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <?php echo FunctionsEdit::selectEditControl('parent', $where_am_i, I18N::translate('All'), $WT_TREE->getTreeId(), 'class="form-control"'); ?> </div> <button type="submit" class="btn btn-default"> <i class="fa fa-download"></i> <?php echo I18N::translate('Download'); ?> </button> </div> </div> </form> <?php }
/** {@inheritdoc} */ public function getTabContent() { global $WT_TREE, $controller; ob_start(); echo '<table class="facts_table">'; foreach ($this->getFactsWithMedia() as $fact) { if ($fact->getTag() == 'OBJE') { FunctionsPrintFacts::printMainMedia($fact, 1); } else { for ($i = 2; $i < 4; ++$i) { FunctionsPrintFacts::printMainMedia($fact, $i); } } } if (!$this->getFactsWithMedia()) { echo '<tr><td id="no_tab4" colspan="2" class="facts_value">', I18N::translate('There are no media objects for this individual.'), '</td></tr>'; } // New media link if ($controller->record->canEdit() && $WT_TREE->getPreference('MEDIA_UPLOAD') >= Auth::accessLevel($controller->record->getTree())) { ?> <tr> <td class="facts_label"> <?php echo GedcomTag::getLabel('OBJE'); ?> </td> <td class="facts_value"> <a href="#" onclick="window.open('addmedia.php?action=showmediaform&linktoid=<?php echo $controller->record->getXref(); ?> &ged=<?php echo $controller->record->getTree()->getNameUrl(); ?> ', '_blank', edit_window_specs); return false;"> <?php echo I18N::translate('Add a new media object'); ?> </a> <?php echo FunctionsPrint::helpLink('OBJE'); ?> <br> <a href="#" onclick="window.open('inverselink.php?linktoid=<?php echo $controller->record->getXref(); ?> &ged=<?php echo $WT_TREE->getNameUrl(); ?> &linkto=person', '_blank', find_window_specs); return false;"> <?php echo I18N::translate('Link to an existing media object'); ?> </a> </td> </tr> <?php } ?> </table> <?php return '<div id="' . $this->getName() . '_content">' . ob_get_clean() . '</div>'; }
/** * Events * * @param string $type * @param string $direction * @param string $facts * * @return string */ private function eventQuery($type, $direction, $facts) { $eventTypes = array('BIRT' => I18N::translate('birth'), 'DEAT' => I18N::translate('death'), 'MARR' => I18N::translate('marriage'), 'ADOP' => I18N::translate('adoption'), 'BURI' => I18N::translate('burial'), 'CENS' => I18N::translate('census added')); $fact_query = "IN ('" . str_replace('|', "','", $facts) . "')"; if ($direction != 'ASC') { $direction = 'DESC'; } $rows = $this->runSql('' . ' SELECT SQL_CACHE' . ' d_gid AS id,' . ' d_year AS year,' . ' d_fact AS fact,' . ' d_type AS type' . ' FROM' . " `##dates`" . ' WHERE' . " d_file={$this->tree->getTreeId()} AND" . " d_gid<>'HEAD' AND" . " d_fact {$fact_query} AND" . ' d_julianday1<>0' . ' ORDER BY' . " d_julianday1 {$direction}, d_type LIMIT 1"); if (!isset($rows[0])) { return ''; } $row = $rows[0]; $record = GedcomRecord::getInstance($row['id'], $this->tree); switch ($type) { default: case 'full': if ($record->canShow()) { $result = $record->formatList('span', false, $record->getFullName()); } else { $result = I18N::translate('This information is private and cannot be shown.'); } break; case 'year': $date = new Date($row['type'] . ' ' . $row['year']); $result = $date->display(); break; case 'type': if (isset($eventTypes[$row['fact']])) { $result = $eventTypes[$row['fact']]; } else { $result = GedcomTag::getLabel($row['fact']); } break; case 'name': $result = "<a href=\"" . $record->getHtmlUrl() . "\">" . $record->getFullName() . "</a>"; break; case 'place': $fact = $record->getFirstFact($row['fact']); if ($fact) { $result = FunctionsPrint::formatFactPlace($fact, true, true, true); } else { $result = I18N::translate('Private'); } break; } return $result; }
/** * Get the name of this fact type, for use as a label. * * @return string */ public function getLabel() { switch ($this->tag) { case 'EVEN': case 'FACT': if ($this->getAttribute('TYPE')) { // Custom FACT/EVEN - with a TYPE return I18N::translate(Filter::escapeHtml($this->getAttribute('TYPE'))); } // no break - drop into next case // no break - drop into next case default: return GedcomTag::getLabel($this->tag, $this->parent); } }
/** * 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 */ public static function printAddNewFact($id, $usedfacts, $type) { global $WT_TREE; // -- Add from clipboard if (is_array(Session::get('clipboard'))) { $newRow = true; foreach (array_reverse(Session::get('clipboard'), true) as $fact_id => $fact) { if ($fact["type"] == $type || $fact["type"] == 'all') { if ($newRow) { $newRow = false; echo '<tr><td class="descriptionbox">'; echo I18N::translate('Add from clipboard'), '</td>'; echo '<td class="optionbox wrap"><form method="get" name="newFromClipboard" action="?" onsubmit="return false;">'; echo '<select id="newClipboardFact">'; } echo '<option value="', Filter::escapeHtml($fact_id), '">', GedcomTag::getLabel($fact['fact']); // TODO use the event class to store/parse the clipboard events if (preg_match('/^2 DATE (.+)/m', $fact['factrec'], $match)) { $tmp = new Date($match[1]); echo '; ', $tmp->minimumDate()->format('%Y'); } if (preg_match('/^2 PLAC ([^,\\n]+)/m', $fact['factrec'], $match)) { echo '; ', $match[1]; } echo '</option>'; } } if (!$newRow) { echo '</select>'; echo ' <input type="button" value="', I18N::translate('Add'), "\" onclick=\"return paste_fact('{$id}', '#newClipboardFact');\"> "; echo '</form></td></tr>', "\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(self::checkFactUnique($uniquefacts, $usedfacts, $type), $addfacts); $quickfacts = array_intersect($quickfacts, $addfacts); $translated_addfacts = array(); foreach ($addfacts as $addfact) { $translated_addfacts[$addfact] = GedcomTag::getLabel($addfact); } uasort($translated_addfacts, function ($x, $y) { return I18N::strcasecmp(I18N::translate($x), I18N::translate($y)); }); echo '<tr><td class="descriptionbox">'; echo I18N::translate('Fact or event'); echo '</td>'; echo '<td class="optionbox wrap">'; echo '<form method="get" name="newfactform" action="?" onsubmit="return false;">'; echo '<select id="newfact" name="newfact">'; echo '<option value="" disabled selected>' . I18N::translate('<select>') . '</option>'; foreach ($translated_addfacts as $fact => $fact_name) { echo '<option value="', $fact, '">', $fact_name, '</option>'; } if ($type == 'INDI' || $type == 'FAM') { echo '<option value="FACT">', I18N::translate('Custom fact'), '</option>'; echo '<option value="EVEN">', I18N::translate('Custom event'), '</option>'; } echo '</select>'; echo '<input type="button" value="', I18N::translate('Add'), '" onclick="add_record(\'' . $id . '\', \'newfact\');">'; echo '<span class="quickfacts">'; foreach ($quickfacts as $fact) { echo '<a href="#" onclick="add_new_record(\'' . $id . '\', \'' . $fact . '\');return false;">', GedcomTag::getLabel($fact), '</a>'; } echo '</span></form>'; echo '</td></tr>'; }
echo I18N::translate('Title'); ?> </label> </th> <td> <input id="Titl" name="Titl" type="text" value="<?php echo $year, ' ', $census->censusPlace(), ' - ', I18N::translate('Census transcript'), ' - ', strip_tags($head->getFullName()), ' - ', I18N::translate('Household'); ?> "> </td> </tr> <tr> <th> <label for="citation"> <?php echo GedcomTag::getLabel('PAGE'); ?> </label> </th> <td> <input id="citation" name="citation" type="text"> </td> </tr> <tr> <th> <label for="locality"> <?php echo I18N::translate('Place'); ?> </label> </th>
/** {@inheritdoc} */ public function getTabContent() { global $WT_TREE, $controller; ob_start(); echo '<table class="facts_table">'; ?> <tr> <td colspan="2" class="descriptionbox rela"> <input id="checkbox_note2" type="checkbox" <?php echo $WT_TREE->getPreference('SHOW_LEVEL2_NOTES') ? 'checked' : ''; ?> onclick="jQuery('tr.row_note2').toggle();"> <label for="checkbox_note2"><?php echo I18N::translate('Show all notes'); ?> </label> </td> </tr> <?php foreach ($this->getFactsWithNotes() as $fact) { if ($fact->getTag() == 'NOTE') { FunctionsPrintFacts::printMainNotes($fact, 1); } else { for ($i = 2; $i < 4; ++$i) { FunctionsPrintFacts::printMainNotes($fact, $i); } } } if (!$this->getFactsWithNotes()) { echo '<tr><td id="no_tab4" colspan="2" class="facts_value">', I18N::translate('There are no notes for this individual.'), '</td></tr>'; } // New note link if ($controller->record->canEdit()) { ?> <tr> <td class="facts_label"> <?php echo GedcomTag::getLabel('NOTE'); ?> </td> <td class="facts_value"> <a href="#" onclick="add_new_record('<?php echo $controller->record->getXref(); ?> ','NOTE'); return false;"> <?php echo I18N::translate('Add a new note'); ?> </a> </td> </tr> <tr> <td class="facts_label"> <?php echo GedcomTag::getLabel('SHARED_NOTE'); ?> </td> <td class="facts_value"> <a href="#" onclick="add_new_record('<?php echo $controller->record->getXref(); ?> ','SHARED_NOTE'); return false;"> <?php echo I18N::translate('Add a new shared note'); ?> </a> </td> </tr> <?php } ?> </table> <?php if (!$WT_TREE->getPreference('SHOW_LEVEL2_NOTES')) { echo '<script>jQuery("tr.row_note2").toggle();</script>'; } return '<div id="' . $this->getName() . '_content">' . ob_get_clean() . '</div>'; }
/** * Find a media object. */ private static function mediaFind() { global $WT_TREE; $controller = new SimpleController(); $filter = Filter::get('filter'); $multiple = Filter::getBool('multiple'); $controller->setPageTitle(I18N::translate('Find an individual'))->pageHeader(); ?> <script> function pasterow(id, name, gend, yob, age, bpl) { window.opener.opener.insertRowToTable(id, name, '', gend, '', yob, age, 'Y', '', bpl); } function pasteid(id, name, thumb) { if (thumb) { window.opener.paste_id(id, name, thumb); <?php if (!$multiple) { echo "window.close();"; } ?> } else { // GEDFact_assistant ======================== if (window.opener.document.getElementById('addlinkQueue')) { window.opener.insertRowToTable(id, name); } window.opener.paste_id(id); if (window.opener.pastename) { window.opener.pastename(name); } <?php if (!$multiple) { echo "window.close();"; } ?> } } function checknames(frm) { if (document.forms[0].subclick) { button = document.forms[0].subclick.value; } else { button = ""; } if (frm.filter.value.length < 2 && button !== "all") { alert("<?php echo I18N::translate('Please enter more than one character.'); ?> "); frm.filter.focus(); return false; } if (button=="all") { frm.filter.value = ""; } return true; } </script> <?php echo '<div>'; echo '<table class="list_table width90" border="0">'; echo '<tr><td style="padding: 10px;" class="facts_label03 width90">'; // start column for find text header echo $controller->getPageTitle(); echo '</td>'; echo '</tr>'; echo '</table>'; echo '<br>'; echo '<button onclick="window.close();">', I18N::translate('close'), '</button>'; echo '<br>'; $filter = trim($filter); $filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter)); echo '<table class="tabs_table width90"><tr>'; $myindilist = FunctionsDb::searchIndividualNames($filter_array, array($WT_TREE)); if ($myindilist) { echo '<td class="list_value_wrap"><ul>'; usort($myindilist, '\\Fisharebest\\Webtrees\\GedcomRecord::compare'); foreach ($myindilist as $indi) { $nam = Filter::escapeHtml($indi->getFullName()); echo "<li><a href=\"#\" onclick=\"pasterow(\n\t\t\t\t\t'" . $indi->getXref() . "' ,\n\t\t\t\t\t'" . $nam . "' ,\n\t\t\t\t\t'" . $indi->getSex() . "' ,\n\t\t\t\t\t'" . $indi->getBirthYear() . "' ,\n\t\t\t\t\t'" . (1901 - $indi->getBirthYear()) . "' ,\n\t\t\t\t\t'" . $indi->getBirthPlace() . "'); return false;\">\n\t\t\t\t\t<b>" . $indi->getFullName() . "</b> "; $born = GedcomTag::getLabel('BIRT'); echo "</span><br><span class=\"list_item\">", $born, " ", $indi->getBirthYear(), " ", $indi->getBirthPlace(), "</span></a></li>"; echo "<hr>"; } echo '</ul></td></tr><tr><td class="list_label">', I18N::translate('Total individuals: %s', count($myindilist)), '</tr></td>'; } else { echo "<td class=\"list_value_wrap\">"; echo I18N::translate('No results found.'); echo "</td></tr>"; } echo "</table>"; echo '</div>'; }
/** * print information for a name record * * @param Fact $event the event object */ public function printNameRecord(Fact $event) { $factrec = $event->getGedcom(); // Create a dummy record, so we can extract the formatted NAME value from the event. $dummy = new Individual('xref', "0 @xref@ INDI\n1 DEAT Y\n" . $factrec, null, $event->getParent()->getTree()); $all_names = $dummy->getAllNames(); $primary_name = $all_names[0]; $this->name_count++; if ($this->name_count > 1) { echo '<h3 class="name_two">', $dummy->getFullName(), '</h3>'; } //Other names accordion element echo '<div class="indi_name_details'; if ($event->isPendingDeletion()) { echo ' old'; } if ($event->isPendingAddition()) { echo ' new'; } echo '">'; echo '<div class="name1">'; echo '<dl><dt class="label">', I18N::translate('Name'), '</dt>'; $dummy->setPrimaryName(0); echo '<dd class="field">', $dummy->getFullName(); if ($this->name_count == 1) { if (Auth::isAdmin()) { $user = User::findByGenealogyRecord($this->record); if ($user) { echo '<span> - <a class="warning" href="admin_users.php?filter=' . Filter::escapeHtml($user->getUserName()) . '">' . Filter::escapeHtml($user->getUserName()) . '</a></span>'; } } } if ($this->record->canEdit() && !$event->isPendingDeletion()) { echo "<div class=\"deletelink\"><a class=\"deleteicon\" href=\"#\" onclick=\"return delete_fact('" . I18N::translate('Are you sure you want to delete this fact?') . "', '" . $this->record->getXref() . "', '" . $event->getFactId() . "');\" title=\"" . I18N::translate('Delete this name') . "\"><span class=\"link_text\">" . I18N::translate('Delete this name') . "</span></a></div>"; echo "<div class=\"editlink\"><a href=\"#\" class=\"editicon\" onclick=\"edit_name('" . $this->record->getXref() . "', '" . $event->getFactId() . "'); return false;\" title=\"" . I18N::translate('Edit name') . "\"><span class=\"link_text\">" . I18N::translate('Edit name') . "</span></a></div>"; } echo '</dd>'; echo '</dl>'; echo '</div>'; $ct = preg_match_all('/\\n2 (\\w+) (.*)/', $factrec, $nmatch, PREG_SET_ORDER); for ($i = 0; $i < $ct; $i++) { echo '<div>'; $fact = $nmatch[$i][1]; if ($fact != 'SOUR' && $fact != 'NOTE' && $fact != 'SPFX') { echo '<dl><dt class="label">', GedcomTag::getLabel($fact, $this->record), '</dt>'; echo '<dd class="field">'; // Before using dir="auto" on this field, note that Gecko treats this as an inline element but WebKit treats it as a block element if (isset($nmatch[$i][2])) { $name = Filter::escapeHtml($nmatch[$i][2]); $name = str_replace('/', '', $name); $name = preg_replace('/(\\S*)\\*/', '<span class="starredname">\\1</span>', $name); switch ($fact) { case 'TYPE': echo GedcomCodeName::getValue($name, $this->record); break; case 'SURN': // The SURN field is not necessarily the surname. // Where it is not a substring of the real surname, show it after the real surname. $surname = Filter::escapeHtml($primary_name['surname']); if (strpos($primary_name['surname'], str_replace(',', ' ', $nmatch[$i][2])) !== false) { echo '<span dir="auto">' . $surname . '</span>'; } else { echo I18N::translate('%1$s (%2$s)', '<span dir="auto">' . $surname . '</span>', '<span dir="auto">' . $name . '</span>'); } break; default: echo '<span dir="auto">' . $name . '</span>'; break; } } echo '</dd>'; echo '</dl>'; } echo '</div>'; } if (preg_match("/\n2 SOUR/", $factrec)) { echo '<div id="indi_sour" class="clearfloat">', FunctionsPrintFacts::printFactSources($factrec, 2), '</div>'; } if (preg_match("/\n2 NOTE/", $factrec)) { echo '<div id="indi_note" class="clearfloat">', FunctionsPrint::printFactNotes($factrec, 2), '</div>'; } echo '</div>'; }
/** * Variable lookup * * Retrieve predefined variables : * * @ desc GEDCOM fact description, example: * 1 EVEN This is a description * @ fact GEDCOM fact tag, such as BIRT, DEAT etc. * $ I18N::translate('....') * $ language_settings[] * * @param array $attrs an array of key value pairs for the attributes */ private function varStartHandler($attrs) { if (empty($attrs['var'])) { throw new \DomainException('REPORT ERROR var: The attribute "var=" is missing or not set in the XML file on line: ' . xml_get_current_line_number($this->parser)); } $var = $attrs['var']; // SetVar element preset variables if (!empty($this->vars[$var]['id'])) { $var = $this->vars[$var]['id']; } else { $tfact = $this->fact; if (($this->fact === "EVEN" || $this->fact === "FACT") && $this->type !== " ") { // Use : // n TYPE This text if string $tfact = $this->type; } $var = str_replace(array("@fact", "@desc"), array(GedcomTag::getLabel($tfact), $this->desc), $var); if (preg_match('/^I18N::number\\((.+)\\)$/', $var, $match)) { $var = I18N::number($match[1]); } elseif (preg_match('/^I18N::translate\\(\'(.+)\'\\)$/', $var, $match)) { $var = I18N::translate($match[1]); } elseif (preg_match('/^I18N::translateContext\\(\'(.+)\', *\'(.+)\'\\)$/', $var, $match)) { $var = I18N::translateContext($match[1], $match[2]); } } // Check if variable is set as a date and reformat the date if (isset($attrs['date'])) { if ($attrs['date'] === "1") { $g = new Date($var); $var = $g->display(); } } $this->current_element->addText($var); $this->text = $var; // Used for title/descriptio }