18c2e8227SGreg Roach<?php 28c2e8227SGreg Roach/** 38c2e8227SGreg Roach * webtrees: online genealogy 4*6bdf7674SGreg Roach * Copyright (C) 2017 webtrees development team 58c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify 68c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by 78c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or 88c2e8227SGreg Roach * (at your option) any later version. 98c2e8227SGreg Roach * This program is distributed in the hope that it will be useful, 108c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 118c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128c2e8227SGreg Roach * GNU General Public License for more details. 138c2e8227SGreg Roach * You should have received a copy of the GNU General Public License 148c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 158c2e8227SGreg Roach */ 1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 1776692c8bSGreg Roach 183a7bc14aSDavid Druryuse Fisharebest\Webtrees\Census\Census; 19ad51e0bbSGreg Roachuse Fisharebest\Webtrees\Census\CensusInterface; 200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Controller\SimpleController; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Family; 220e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter; 23ad51e0bbSGreg Roachuse Fisharebest\Webtrees\Functions\Functions; 243d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsDb; 250e62c4b8SGreg Roachuse Fisharebest\Webtrees\GedcomRecord; 260e62c4b8SGreg Roachuse Fisharebest\Webtrees\GedcomTag; 270e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 2899f222b3SGreg Roachuse Fisharebest\Webtrees\Individual; 29ad51e0bbSGreg Roachuse Fisharebest\Webtrees\Menu; 300e62c4b8SGreg Roachuse Fisharebest\Webtrees\Note; 31dc46b574SDavid Druryuse Fisharebest\Webtrees\Soundex; 328c2e8227SGreg Roach 338c2e8227SGreg Roach/** 348c2e8227SGreg Roach * Class CensusAssistantModule 358c2e8227SGreg Roach */ 3615834aaeSGreg Roachclass CensusAssistantModule extends AbstractModule { 378c2e8227SGreg Roach /** {@inheritdoc} */ 388c2e8227SGreg Roach public function getTitle() { 398c2e8227SGreg Roach return /* I18N: Name of a module */ I18N::translate('Census assistant'); 408c2e8227SGreg Roach } 418c2e8227SGreg Roach 428c2e8227SGreg Roach /** {@inheritdoc} */ 438c2e8227SGreg Roach public function getDescription() { 448c2e8227SGreg Roach return /* I18N: Description of the “Census assistant” module */ I18N::translate('An alternative way to enter census transcripts and link them to individuals.'); 458c2e8227SGreg Roach } 468c2e8227SGreg Roach 4776692c8bSGreg Roach /** 4876692c8bSGreg Roach * This is a general purpose hook, allowing modules to respond to routes 4976692c8bSGreg Roach * of the form module.php?mod=FOO&mod_action=BAR 5076692c8bSGreg Roach * 5176692c8bSGreg Roach * @param string $mod_action 5276692c8bSGreg Roach */ 538c2e8227SGreg Roach public function modAction($mod_action) { 548c2e8227SGreg Roach switch ($mod_action) { 5540990b78SGreg Roach case 'census_find': 5640990b78SGreg Roach self::censusFind(); 578c2e8227SGreg Roach break; 5840990b78SGreg Roach case 'media_find': 59764a01d9SGreg Roach self::mediaFind(); 608c2e8227SGreg Roach break; 618c2e8227SGreg Roach case 'media_query_3a': 62764a01d9SGreg Roach self::mediaQuery(); 638c2e8227SGreg Roach break; 648c2e8227SGreg Roach default: 658c2e8227SGreg Roach http_response_code(404); 668c2e8227SGreg Roach } 678c2e8227SGreg Roach } 688c2e8227SGreg Roach 698c2e8227SGreg Roach /** 7076692c8bSGreg Roach * Find an individual. 718c2e8227SGreg Roach */ 7240990b78SGreg Roach private static function censusFind() { 7340990b78SGreg Roach global $WT_TREE; 7440990b78SGreg Roach 7540990b78SGreg Roach $controller = new SimpleController; 7640990b78SGreg Roach $filter = Filter::get('filter'); 7740990b78SGreg Roach $action = Filter::get('action'); 78ad51e0bbSGreg Roach $census = Filter::get('census'); 79ad51e0bbSGreg Roach $census = new $census; 8040990b78SGreg Roach 8140990b78SGreg Roach $controller 82ad51e0bbSGreg Roach ->restrictAccess($census instanceof CensusInterface) 8340990b78SGreg Roach ->setPageTitle(I18N::translate('Find an individual')) 8440990b78SGreg Roach ->pageHeader(); 8540990b78SGreg Roach 86ad51e0bbSGreg Roach echo '<table class="list_table width90" border="0">'; 87a86dd8b1SGreg Roach echo '<tr><td style="padding: 10px;" class="facts_label03 width90">'; 8840990b78SGreg Roach echo I18N::translate('Find an individual'); 89ad51e0bbSGreg Roach echo '</td>'; 90ad51e0bbSGreg Roach echo '</table>'; 91ad51e0bbSGreg Roach echo '<br>'; 9240990b78SGreg Roach 93ad51e0bbSGreg Roach if ($action == 'filter') { 9440990b78SGreg Roach $filter = trim($filter); 9540990b78SGreg Roach $filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter)); 9640990b78SGreg Roach 9740990b78SGreg Roach // Output Individual for GEDFact Assistant ====================== 98ad51e0bbSGreg Roach echo '<table class="list_table width90">'; 9913abd6f3SGreg Roach $myindilist = FunctionsDb::searchIndividualNames($filter_array, [$WT_TREE]); 10040990b78SGreg Roach if ($myindilist) { 101ad51e0bbSGreg Roach echo '<tr><td class="list_value_wrap"><ul>'; 10240990b78SGreg Roach usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare'); 10340990b78SGreg Roach foreach ($myindilist as $indi) { 104ad51e0bbSGreg Roach echo '<li>'; 1050b18a98dSGreg Roach echo '<a href="#" onclick="window.opener.appendCensusRow(\'' . Filter::escapeJs(self::censusTableRow($census, $indi, null)) . '\'); window.close();">'; 106ad51e0bbSGreg Roach echo '<b>' . $indi->getFullName() . '</b>'; 107ad51e0bbSGreg Roach echo '</a>'; 108ad51e0bbSGreg Roach echo $indi->formatFirstMajorFact(WT_EVENTS_BIRT, 1); 109ad51e0bbSGreg Roach echo $indi->formatFirstMajorFact(WT_EVENTS_DEAT, 1); 110ad51e0bbSGreg Roach echo '<hr>'; 111ad51e0bbSGreg Roach echo '</li>'; 11240990b78SGreg Roach } 11340990b78SGreg Roach echo '</ul></td></tr>'; 11440990b78SGreg Roach } else { 115ad51e0bbSGreg Roach echo '<tr><td class="list_value_wrap">'; 11640990b78SGreg Roach echo I18N::translate('No results found.'); 117ad51e0bbSGreg Roach echo '</td></tr>'; 11840990b78SGreg Roach } 119ad51e0bbSGreg Roach echo '<tr><td>'; 12040990b78SGreg Roach echo '<button onclick="window.close();">', I18N::translate('close'), '</button>'; 121ad51e0bbSGreg Roach echo '</td></tr>'; 122ad51e0bbSGreg Roach echo '</table>'; 123ad51e0bbSGreg Roach } 12440990b78SGreg Roach } 12540990b78SGreg Roach 12640990b78SGreg Roach /** 12776692c8bSGreg Roach * Find a media object. 12840990b78SGreg Roach */ 129764a01d9SGreg Roach private static function mediaFind() { 1308c2e8227SGreg Roach global $WT_TREE; 1318c2e8227SGreg Roach 1328c2e8227SGreg Roach $controller = new SimpleController; 1338c2e8227SGreg Roach $filter = Filter::get('filter'); 1348c2e8227SGreg Roach $multiple = Filter::getBool('multiple'); 1358c2e8227SGreg Roach 1368c2e8227SGreg Roach $controller 1378c2e8227SGreg Roach ->setPageTitle(I18N::translate('Find an individual')) 1388c2e8227SGreg Roach ->pageHeader(); 1398c2e8227SGreg Roach 1408c2e8227SGreg Roach ?> 14199f222b3SGreg Roach <script> 1428c2e8227SGreg Roach function pasterow(id, name, gend, yob, age, bpl) { 1438c2e8227SGreg Roach window.opener.opener.insertRowToTable(id, name, '', gend, '', yob, age, 'Y', '', bpl); 1448c2e8227SGreg Roach } 1458c2e8227SGreg Roach 1468c2e8227SGreg Roach function pasteid(id, name, thumb) { 1478c2e8227SGreg Roach if (thumb) { 1488c2e8227SGreg Roach window.opener.paste_id(id, name, thumb); 1497a6ee1acSGreg Roach <?php if (!$multiple) { echo 'window.close();'; } ?> 1508c2e8227SGreg Roach } else { 1518c2e8227SGreg Roach // GEDFact_assistant ======================== 1528c2e8227SGreg Roach if (window.opener.document.getElementById('addlinkQueue')) { 1538c2e8227SGreg Roach window.opener.insertRowToTable(id, name); 1548c2e8227SGreg Roach } 1558c2e8227SGreg Roach window.opener.paste_id(id); 1568c2e8227SGreg Roach if (window.opener.pastename) { 1578c2e8227SGreg Roach window.opener.pastename(name); 1588c2e8227SGreg Roach } 1597a6ee1acSGreg Roach <?php if (!$multiple) { echo 'window.close();'; } ?> 1608c2e8227SGreg Roach } 1618c2e8227SGreg Roach } 1628c2e8227SGreg Roach function checknames(frm) { 1638c2e8227SGreg Roach if (document.forms[0].subclick) { 1648c2e8227SGreg Roach button = document.forms[0].subclick.value; 1658c2e8227SGreg Roach } else { 1668c2e8227SGreg Roach button = ""; 1678c2e8227SGreg Roach } 168ad51e0bbSGreg Roach if (frm.filter.value.length < 2 && button !== "all") { 169564ae2d7SGreg Roach alert("<?= I18N::translate('Please enter more than one character.') ?>"); 1708c2e8227SGreg Roach frm.filter.focus(); 1718c2e8227SGreg Roach return false; 1728c2e8227SGreg Roach } 1738c2e8227SGreg Roach if (button=="all") { 1748c2e8227SGreg Roach frm.filter.value = ""; 1758c2e8227SGreg Roach } 1768c2e8227SGreg Roach return true; 1778c2e8227SGreg Roach } 17899f222b3SGreg Roach </script> 1798c2e8227SGreg Roach 18099f222b3SGreg Roach <?php 181a86dd8b1SGreg Roach echo '<div>'; 1824c621133SGreg Roach echo '<table class="list_table width90" border="0">'; 183a86dd8b1SGreg Roach echo '<tr><td style="padding: 10px;" class="facts_label03 width90">'; // start column for find text header 1848c2e8227SGreg Roach echo $controller->getPageTitle(); 1854c621133SGreg Roach echo '</td>'; 1864c621133SGreg Roach echo '</tr>'; 1874c621133SGreg Roach echo '</table>'; 1884c621133SGreg Roach echo '<br>'; 1898c2e8227SGreg Roach echo '<button onclick="window.close();">', I18N::translate('close'), '</button>'; 1904c621133SGreg Roach echo '<br>'; 1918c2e8227SGreg Roach 1928c2e8227SGreg Roach $filter = trim($filter); 1938c2e8227SGreg Roach $filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter)); 1944c621133SGreg Roach echo '<table class="tabs_table width90"><tr>'; 19513abd6f3SGreg Roach $myindilist = FunctionsDb::searchIndividualNames($filter_array, [$WT_TREE]); 1968c2e8227SGreg Roach if ($myindilist) { 1974c621133SGreg Roach echo '<td class="list_value_wrap"><ul>'; 1980e62c4b8SGreg Roach usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare'); 1998c2e8227SGreg Roach foreach ($myindilist as $indi) { 2008c2e8227SGreg Roach $nam = Filter::escapeHtml($indi->getFullName()); 2018c2e8227SGreg Roach echo "<li><a href=\"#\" onclick=\"pasterow( 2028c2e8227SGreg Roach '" . $indi->getXref() . "' , 2038c2e8227SGreg Roach '" . $nam . "' , 2048c2e8227SGreg Roach '" . $indi->getSex() . "' , 2057820e4d7SGreg Roach '" . $indi->getBirthYear() . "' , 2067820e4d7SGreg Roach '" . (1901 - $indi->getBirthYear()) . "' , 2077820e4d7SGreg Roach '" . $indi->getBirthPlace() . "'); return false;\"> 2087a6ee1acSGreg Roach <b>" . $indi->getFullName() . '</b> '; 2098c2e8227SGreg Roach 210564ae2d7SGreg Roach $born = I18N::translate('Birth'); 2117a6ee1acSGreg Roach echo '</span><br><span class="list_item">', $born, ' ', $indi->getBirthYear(), ' ', $indi->getBirthPlace(), '</span></a></li>'; 2127a6ee1acSGreg Roach echo '<hr>'; 2138c2e8227SGreg Roach } 2148c2e8227SGreg Roach echo '</ul></td></tr><tr><td class="list_label">', I18N::translate('Total individuals: %s', count($myindilist)), '</tr></td>'; 2158c2e8227SGreg Roach } else { 2167a6ee1acSGreg Roach echo '<td class="list_value_wrap">'; 2178c2e8227SGreg Roach echo I18N::translate('No results found.'); 2187a6ee1acSGreg Roach echo '</td></tr>'; 2198c2e8227SGreg Roach } 2207a6ee1acSGreg Roach echo '</table>'; 2218c2e8227SGreg Roach echo '</div>'; 2228c2e8227SGreg Roach } 2238c2e8227SGreg Roach 2248c2e8227SGreg Roach /** 22576692c8bSGreg Roach * Search for a media object. 2268c2e8227SGreg Roach */ 227764a01d9SGreg Roach private static function mediaQuery() { 22824ec66ceSGreg Roach global $WT_TREE; 22924ec66ceSGreg Roach 2308c2e8227SGreg Roach $iid2 = Filter::get('iid', WT_REGEX_XREF); 2318c2e8227SGreg Roach 2328c2e8227SGreg Roach $controller = new SimpleController; 2338c2e8227SGreg Roach $controller 2348c2e8227SGreg Roach ->setPageTitle(I18N::translate('Link to an existing media object')) 2358c2e8227SGreg Roach ->pageHeader(); 2368c2e8227SGreg Roach 23724ec66ceSGreg Roach $record = GedcomRecord::getInstance($iid2, $WT_TREE); 2388c2e8227SGreg Roach if ($record) { 2398c2e8227SGreg Roach $headjs = ''; 2408c2e8227SGreg Roach if ($record instanceof Family) { 2418c2e8227SGreg Roach if ($record->getHusband()) { 2428c2e8227SGreg Roach $headjs = $record->getHusband()->getXref(); 2438c2e8227SGreg Roach } elseif ($record->getWife()) { 2448c2e8227SGreg Roach $headjs = $record->getWife()->getXref(); 2458c2e8227SGreg Roach } 2468c2e8227SGreg Roach } 2478c2e8227SGreg Roach ?> 2488c2e8227SGreg Roach <script> 2498c2e8227SGreg Roach function insertId() { 2508c2e8227SGreg Roach if (window.opener.document.getElementById('addlinkQueue')) { 2518c2e8227SGreg Roach // alert('Please move this alert window and examine the contents of the pop-up window, then click OK') 252564ae2d7SGreg Roach window.opener.insertRowToTable('<?= $record->getXref() ?>', '<?= htmlspecialchars($record->getFullName()) ?>', '<?= $headjs ?>'); 2538c2e8227SGreg Roach window.close(); 2548c2e8227SGreg Roach } 2558c2e8227SGreg Roach } 2568c2e8227SGreg Roach </script> 2578c2e8227SGreg Roach <?php 2588c2e8227SGreg Roach } else { 2598c2e8227SGreg Roach ?> 2608c2e8227SGreg Roach <script> 2618c2e8227SGreg Roach function insertId() { 262564ae2d7SGreg Roach window.opener.alert('<?= $iid2 ?> - <?= I18N::translate('Not a valid individual, family, or source ID') ?>'); 2638c2e8227SGreg Roach window.close(); 2648c2e8227SGreg Roach } 2658c2e8227SGreg Roach </script> 2668c2e8227SGreg Roach <?php 2678c2e8227SGreg Roach } 2688c2e8227SGreg Roach ?> 2698c2e8227SGreg Roach <script>window.onLoad = insertId();</script> 2708c2e8227SGreg Roach <?php 2718c2e8227SGreg Roach } 2728c2e8227SGreg Roach 2738c2e8227SGreg Roach /** 2748c2e8227SGreg Roach * Convert custom markup into HTML 2758c2e8227SGreg Roach * 2768c2e8227SGreg Roach * @param Note $note 2778c2e8227SGreg Roach * 2788c2e8227SGreg Roach * @return string 2798c2e8227SGreg Roach */ 2808c2e8227SGreg Roach public static function formatCensusNote(Note $note) { 2818c2e8227SGreg Roach global $WT_TREE; 2828c2e8227SGreg Roach 28314c3d3fbSGreg Roach if (preg_match('/(.*)((?:\n.*)*)\n\.start_formatted_area\.\n(.+)\n(.+(?:\n.+)*)\n.end_formatted_area\.((?:\n.*)*)/', $note->getNote(), $match)) { 2848c2e8227SGreg Roach // This looks like a census-assistant shared note 2858c2e8227SGreg Roach $title = Filter::escapeHtml($match[1]); 2868c2e8227SGreg Roach $preamble = Filter::escapeHtml($match[2]); 2878c2e8227SGreg Roach $header = Filter::escapeHtml($match[3]); 2888c2e8227SGreg Roach $data = Filter::escapeHtml($match[4]); 2898c2e8227SGreg Roach $postamble = Filter::escapeHtml($match[5]); 2908c2e8227SGreg Roach 291dc46b574SDavid Drury // Get the column headers for the census to which this note refers 292dc46b574SDavid Drury // requires the fact place & date to match the specific census 293dc46b574SDavid Drury // censusPlace() (Soundex match) and censusDate() functions 29413abd6f3SGreg Roach $fmt_headers = []; 295dc46b574SDavid Drury $linkedRecords = array_merge($note->linkedIndividuals('NOTE'), $note->linkedFamilies('NOTE')); 296dc46b574SDavid Drury $firstRecord = array_shift($linkedRecords); 297dc46b574SDavid Drury if ($firstRecord) { 298dc46b574SDavid Drury $countryCode = ''; 299dc46b574SDavid Drury $date = ''; 300dc46b574SDavid Drury foreach ($firstRecord->getFacts('CENS') as $fact) { 301dc46b574SDavid Drury if (trim($fact->getAttribute('NOTE'), '@') === $note->getXref()) { 302dc46b574SDavid Drury $date = $fact->getAttribute('DATE'); 303dc46b574SDavid Drury $place = explode(',', strip_tags($fact->getPlace()->getFullName())); 304dc46b574SDavid Drury $countryCode = Soundex::daitchMokotoff(array_pop($place)); 305dc46b574SDavid Drury break; 306dc46b574SDavid Drury } 3078c2e8227SGreg Roach } 3088c2e8227SGreg Roach 309dc46b574SDavid Drury foreach (Census::allCensusPlaces() as $censusPlace) { 310dc46b574SDavid Drury if (Soundex::compare($countryCode, Soundex::daitchMokotoff($censusPlace->censusPlace()))) { 311dc46b574SDavid Drury foreach ($censusPlace->allCensusDates() as $census) { 312dc46b574SDavid Drury if ($census->censusDate() == $date) { 313dc46b574SDavid Drury foreach ($census->columns() as $column) { 314dc46b574SDavid Drury $abbrev = $column->abbreviation(); 315dc46b574SDavid Drury if ($abbrev) { 316dc46b574SDavid Drury $description = $column->title() ? $column->title() : I18N::translate('Description unavailable'); 317dc46b574SDavid Drury $fmt_headers[$abbrev] = '<span title="' . $description . '">' . $abbrev . '</span>'; 318dc46b574SDavid Drury } 319dc46b574SDavid Drury } 320dc46b574SDavid Drury break 2; 321dc46b574SDavid Drury } 322dc46b574SDavid Drury } 323dc46b574SDavid Drury } 324dc46b574SDavid Drury } 325dc46b574SDavid Drury } 326dc46b574SDavid Drury // Substitute header labels and format as HTML 3278c2e8227SGreg Roach $thead = '<tr><th>' . strtr(str_replace('|', '</th><th>', $header), $fmt_headers) . '</th></tr>'; 328ad51e0bbSGreg Roach $thead = str_replace('.b.', '', $thead); 3298c2e8227SGreg Roach 3308c2e8227SGreg Roach // Format data as HTML 3318c2e8227SGreg Roach $tbody = ''; 33214c3d3fbSGreg Roach foreach (explode("\n", $data) as $row) { 3338c2e8227SGreg Roach $tbody .= '<tr>'; 3348c2e8227SGreg Roach foreach (explode('|', $row) as $column) { 3358c2e8227SGreg Roach $tbody .= '<td>' . $column . '</td>'; 3368c2e8227SGreg Roach } 3378c2e8227SGreg Roach $tbody .= '</tr>'; 3388c2e8227SGreg Roach } 3398c2e8227SGreg Roach 3408c2e8227SGreg Roach return 3418c2e8227SGreg Roach $title . "\n" . // The newline allows the framework to expand the details and turn the first line into a link 342673157b0SGreg Roach '<div class="markdown">' . 3438c2e8227SGreg Roach '<p>' . $preamble . '</p>' . 344dc46b574SDavid Drury '<table>' . 3458c2e8227SGreg Roach '<thead>' . $thead . '</thead>' . 3468c2e8227SGreg Roach '<tbody>' . $tbody . '</tbody>' . 3478c2e8227SGreg Roach '</table>' . 348dc46b574SDavid Drury '<p>' . $postamble . '</p>' . 349dc46b574SDavid Drury '</div>'; 3508c2e8227SGreg Roach } else { 3518c2e8227SGreg Roach // Not a census-assistant shared note - apply default formatting 3528c2e8227SGreg Roach return Filter::formatText($note->getNote(), $WT_TREE); 3538c2e8227SGreg Roach } 3548c2e8227SGreg Roach } 35599f222b3SGreg Roach 35699f222b3SGreg Roach /** 357ad51e0bbSGreg Roach * Generate an HTML row of data for the census header 35899f222b3SGreg Roach * 35952bc9faeSGreg Roach * Add prefix cell (store XREF and drag/drop) 36052bc9faeSGreg Roach * Add suffix cell (delete button) 36152bc9faeSGreg Roach * 362ad51e0bbSGreg Roach * @param CensusInterface $census 36399f222b3SGreg Roach * 364ad51e0bbSGreg Roach * @return string 36599f222b3SGreg Roach */ 366ad51e0bbSGreg Roach public static function censusTableHeader(CensusInterface $census) { 36752bc9faeSGreg Roach $html = ''; 368ad51e0bbSGreg Roach foreach ($census->columns() as $column) { 369ad51e0bbSGreg Roach $html .= '<th title="' . $column->title() . '">' . $column->abbreviation() . '</th>'; 37099f222b3SGreg Roach } 37199f222b3SGreg Roach 372dc46b574SDavid Drury return '<tr><th hidden></th>' . $html . '<th></th></tr>'; 373ad51e0bbSGreg Roach } 37499f222b3SGreg Roach 375ad51e0bbSGreg Roach /** 376ad51e0bbSGreg Roach * Generate an HTML row of data for the census 377ad51e0bbSGreg Roach * 37852bc9faeSGreg Roach * Add prefix cell (store XREF and drag/drop) 37952bc9faeSGreg Roach * Add suffix cell (delete button) 38052bc9faeSGreg Roach * 381ad51e0bbSGreg Roach * @param CensusInterface $census 382ad51e0bbSGreg Roach * 383ad51e0bbSGreg Roach * @return string 384ad51e0bbSGreg Roach */ 385ad51e0bbSGreg Roach public static function censusTableEmptyRow(CensusInterface $census) { 38652bc9faeSGreg Roach return '<tr><td hidden></td>' . str_repeat('<td><input type="text"></td>', count($census->columns())) . '<td><a class="icon-remove" href="#" title="' . I18N::translate('Remove') . '"></a></td></tr>'; 387ad51e0bbSGreg Roach } 38899f222b3SGreg Roach 389ad51e0bbSGreg Roach /** 390ad51e0bbSGreg Roach * Generate an HTML row of data for the census 391ad51e0bbSGreg Roach * 39252bc9faeSGreg Roach * Add prefix cell (store XREF and drag/drop) 39352bc9faeSGreg Roach * Add suffix cell (delete button) 39452bc9faeSGreg Roach * 395ad51e0bbSGreg Roach * @param CensusInterface $census 396ad51e0bbSGreg Roach * @param Individual $individual 397ad51e0bbSGreg Roach * @param Individual|null $head 398ad51e0bbSGreg Roach * 399ad51e0bbSGreg Roach * @return string 400ad51e0bbSGreg Roach */ 401ad51e0bbSGreg Roach public static function censusTableRow(CensusInterface $census, Individual $individual, Individual $head = null) { 40252bc9faeSGreg Roach $html = ''; 403ad51e0bbSGreg Roach foreach ($census->columns() as $column) { 404ad51e0bbSGreg Roach $html .= '<td><input type="text" value="' . $column->generate($individual, $head) . '"></td>'; 405ad51e0bbSGreg Roach } 406ad51e0bbSGreg Roach 40752bc9faeSGreg Roach return '<tr><td hidden>' . $individual->getXref() . '</td>' . $html . '<td><a class="icon-remove" href="#" title="' . I18N::translate('Remove') . '"></a></td></tr>'; 408ad51e0bbSGreg Roach } 409ad51e0bbSGreg Roach 410ad51e0bbSGreg Roach /** 411ad51e0bbSGreg Roach * Create a family on the census navigator. 412ad51e0bbSGreg Roach * 413ad51e0bbSGreg Roach * @param CensusInterface $census 414ad51e0bbSGreg Roach * @param Family $family 415ad51e0bbSGreg Roach * @param Individual $head 416ad51e0bbSGreg Roach * 417ad51e0bbSGreg Roach * @return string 418ad51e0bbSGreg Roach */ 419ad51e0bbSGreg Roach public static function censusNavigatorFamily(CensusInterface $census, Family $family, Individual $head) { 4202a277e58SGreg Roach $headImg2 = '<i class="icon-button_head" title="' . I18N::translate('Head of household') . '"></i>'; 421ad51e0bbSGreg Roach 422ad51e0bbSGreg Roach foreach ($family->getSpouses() as $spouse) { 423ad51e0bbSGreg Roach $menu = new Menu(Functions::getCloseRelationshipName($head, $spouse)); 424ad51e0bbSGreg Roach foreach ($spouse->getChildFamilies() as $grandparents) { 425ad51e0bbSGreg Roach foreach ($grandparents->getSpouses() as $grandparent) { 426ad51e0bbSGreg Roach $submenu = new Menu( 427ad51e0bbSGreg Roach Functions::getCloseRelationshipName($head, $grandparent) . ' - ' . $grandparent->getFullName(), 428ad51e0bbSGreg Roach '#', 429ad51e0bbSGreg Roach '', 43013abd6f3SGreg Roach ['onclick' => 'return appendCensusRow("' . Filter::escapeJs(self::censusTableRow($census, $grandparent, $head)) . '");'] 431ad51e0bbSGreg Roach ); 432ad51e0bbSGreg Roach $submenu->addClass('submenuitem', ''); 433ad51e0bbSGreg Roach $menu->addSubmenu($submenu); 434ad51e0bbSGreg Roach $menu->addClass('', 'submenu'); 43599f222b3SGreg Roach } 43699f222b3SGreg Roach } 43799f222b3SGreg Roach 438ad51e0bbSGreg Roach ?> 439ad51e0bbSGreg Roach <tr> 440ad51e0bbSGreg Roach <td class="optionbox"> 441564ae2d7SGreg Roach <?= $menu->getMenu() ?> 442ad51e0bbSGreg Roach </td> 443ad51e0bbSGreg Roach <td class="facts_value nowrap"> 444564ae2d7SGreg Roach <a href="#" onclick="return appendCensusRow('<?= Filter::escapeJs(self::censusTableRow($census, $spouse, $head)) ?>');"> 445564ae2d7SGreg Roach <?= $spouse->getFullName() ?> 446ad51e0bbSGreg Roach </a> 447ad51e0bbSGreg Roach </td> 448a86dd8b1SGreg Roach <td class="facts_value"> 4492a277e58SGreg Roach <?php if ($head !== $spouse): ?> 450564ae2d7SGreg Roach <a href="edit_interface.php?action=addnewnote_assisted&noteid=newnote&xref=<?= $spouse->getXref() ?>&gedcom=<?= $spouse->getTree()->getNameUrl() ?>&census=<?= get_class($census) ?>"> 451564ae2d7SGreg Roach <?= $headImg2 ?> 452ad51e0bbSGreg Roach </a> 453564ae2d7SGreg Roach <?php endif ?> 454ad51e0bbSGreg Roach </td> 455ad51e0bbSGreg Roach </tr> 456ad51e0bbSGreg Roach <?php 45799f222b3SGreg Roach } 458ad51e0bbSGreg Roach 459ad51e0bbSGreg Roach foreach ($family->getChildren() as $child) { 460ad51e0bbSGreg Roach $menu = new Menu(Functions::getCloseRelationshipName($head, $child)); 461ad51e0bbSGreg Roach foreach ($child->getSpouseFamilies() as $spouse_family) { 462ad51e0bbSGreg Roach foreach ($spouse_family->getSpouses() as $spouse_family_spouse) { 463ad51e0bbSGreg Roach if ($spouse_family_spouse != $child) { 464ad51e0bbSGreg Roach $submenu = new Menu( 465ad51e0bbSGreg Roach Functions::getCloseRelationshipName($head, $spouse_family_spouse) . ' - ' . $spouse_family_spouse->getFullName(), 466ad51e0bbSGreg Roach '#', 467ad51e0bbSGreg Roach '', 46813abd6f3SGreg Roach ['onclick' => 'return appendCensusRow("' . Filter::escapeJs(self::censusTableRow($census, $spouse_family_spouse, $head)) . '");'] 469ad51e0bbSGreg Roach ); 470ad51e0bbSGreg Roach $submenu->addClass('submenuitem', ''); 471ad51e0bbSGreg Roach $menu->addSubmenu($submenu); 472ad51e0bbSGreg Roach $menu->addClass('', 'submenu'); 473ad51e0bbSGreg Roach } 474ad51e0bbSGreg Roach } 475ad51e0bbSGreg Roach foreach ($spouse_family->getChildren() as $spouse_family_child) { 476ad51e0bbSGreg Roach $submenu = new Menu( 477ad51e0bbSGreg Roach Functions::getCloseRelationshipName($head, $spouse_family_child) . ' - ' . $spouse_family_child->getFullName(), 478ad51e0bbSGreg Roach '#', 479ad51e0bbSGreg Roach '', 48013abd6f3SGreg Roach ['onclick' => 'return appendCensusRow("' . Filter::escapeJs(self::censusTableRow($census, $spouse_family_child, $head)) . '");'] 481ad51e0bbSGreg Roach ); 482ad51e0bbSGreg Roach $submenu->addClass('submenuitem', ''); 483ad51e0bbSGreg Roach $menu->addSubmenu($submenu); 484ad51e0bbSGreg Roach $menu->addClass('', 'submenu'); 48599f222b3SGreg Roach } 48699f222b3SGreg Roach } 48799f222b3SGreg Roach 488ad51e0bbSGreg Roach ?> 489ad51e0bbSGreg Roach <tr> 490ad51e0bbSGreg Roach <td class="optionbox"> 491564ae2d7SGreg Roach <?= $menu->getMenu() ?> 492ad51e0bbSGreg Roach </td> 493ad51e0bbSGreg Roach <td class="facts_value"> 494564ae2d7SGreg Roach <a href="#" onclick="return appendCensusRow('<?= Filter::escapeJs(self::censusTableRow($census, $child, $head)) ?>');"> 495564ae2d7SGreg Roach <?= $child->getFullName() ?> 496ad51e0bbSGreg Roach </a> 497ad51e0bbSGreg Roach </td> 498ad51e0bbSGreg Roach <td class="facts_value"> 4992a277e58SGreg Roach <?php if ($head !== $child): ?> 500564ae2d7SGreg Roach <a href="edit_interface.php?action=addnewnote_assisted&noteid=newnote&xref=<?= $child->getXref() ?>&gedcom=<?= $child->getTree()->getNameUrl() ?>&census=<?= get_class($census) ?>"> 501564ae2d7SGreg Roach <?= $headImg2 ?> 502ad51e0bbSGreg Roach </a> 503564ae2d7SGreg Roach <?php endif ?> 504ad51e0bbSGreg Roach </td> 505ad51e0bbSGreg Roach </tr> 506ad51e0bbSGreg Roach <?php 50799f222b3SGreg Roach } 508ad51e0bbSGreg Roach echo '<tr><td><br></td></tr>'; 50999f222b3SGreg Roach } 5108c2e8227SGreg Roach} 511