18c2e8227SGreg Roach<?php 28c2e8227SGreg Roach/** 38c2e8227SGreg Roach * webtrees: online genealogy 46bdf7674SGreg 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 */ 1615d603e7SGreg Roach 1776692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 1876692c8bSGreg Roach 193a7bc14aSDavid Druryuse Fisharebest\Webtrees\Census\Census; 20ad51e0bbSGreg Roachuse Fisharebest\Webtrees\Census\CensusInterface; 210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Family; 220e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter; 2315d603e7SGreg Roachuse Fisharebest\Webtrees\FontAwesome; 243d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsDb; 2515d603e7SGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsEdit; 260e62c4b8SGreg Roachuse Fisharebest\Webtrees\GedcomRecord; 27047f239bSGreg Roachuse Fisharebest\Webtrees\Html; 280e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 2999f222b3SGreg Roachuse Fisharebest\Webtrees\Individual; 300e62c4b8SGreg Roachuse Fisharebest\Webtrees\Note; 31dc46b574SDavid Druryuse Fisharebest\Webtrees\Soundex; 3234cd602eSGreg Roachuse Fisharebest\Webtrees\View; 338c2e8227SGreg Roach 348c2e8227SGreg Roach/** 358c2e8227SGreg Roach * Class CensusAssistantModule 368c2e8227SGreg Roach */ 3715834aaeSGreg Roachclass CensusAssistantModule extends AbstractModule { 388c2e8227SGreg Roach /** {@inheritdoc} */ 398c2e8227SGreg Roach public function getTitle() { 4015d603e7SGreg Roach return /* I18N: Name of a module */ 4115d603e7SGreg Roach I18N::translate('Census assistant'); 428c2e8227SGreg Roach } 438c2e8227SGreg Roach 448c2e8227SGreg Roach /** {@inheritdoc} */ 458c2e8227SGreg Roach public function getDescription() { 4615d603e7SGreg Roach return /* I18N: Description of the “Census assistant” module */ 4715d603e7SGreg Roach I18N::translate('An alternative way to enter census transcripts and link them to individuals.'); 488c2e8227SGreg Roach } 498c2e8227SGreg Roach 5076692c8bSGreg Roach /** 5176692c8bSGreg Roach * This is a general purpose hook, allowing modules to respond to routes 5276692c8bSGreg Roach * of the form module.php?mod=FOO&mod_action=BAR 5376692c8bSGreg Roach * 5476692c8bSGreg Roach * @param string $mod_action 5576692c8bSGreg Roach */ 568c2e8227SGreg Roach public function modAction($mod_action) { 5715d603e7SGreg Roach global $WT_TREE; 5815d603e7SGreg Roach 598c2e8227SGreg Roach switch ($mod_action) { 6015d603e7SGreg Roach case 'census-header': 6115d603e7SGreg Roach header('Content-Type: text/html; charset=utf8'); 6215d603e7SGreg Roach $census = Filter::get('census'); 6315d603e7SGreg Roach echo $this->censusTableHeader(new $census); 648c2e8227SGreg Roach break; 6515d603e7SGreg Roach 6615d603e7SGreg Roach case 'census-individual': 6715d603e7SGreg Roach header('Content-Type: text/html; charset=utf8'); 6815d603e7SGreg Roach $census = Filter::get('census'); 6915d603e7SGreg Roach $individual = Individual::getInstance(Filter::get('xref'), $WT_TREE); 7015d603e7SGreg Roach $head = Individual::getInstance(Filter::get('head'), $WT_TREE); 7115d603e7SGreg Roach echo $this->censusTableRow(new $census, $individual, $head); 7215d603e7SGreg Roach break; 7315d603e7SGreg Roach 7440990b78SGreg Roach case 'media_find': 75764a01d9SGreg Roach self::mediaFind(); 768c2e8227SGreg Roach break; 778c2e8227SGreg Roach case 'media_query_3a': 78764a01d9SGreg Roach self::mediaQuery(); 798c2e8227SGreg Roach break; 808c2e8227SGreg Roach default: 818c2e8227SGreg Roach http_response_code(404); 828c2e8227SGreg Roach } 838c2e8227SGreg Roach } 848c2e8227SGreg Roach 858c2e8227SGreg Roach /** 8615d603e7SGreg Roach * @param Individual $individual 878c2e8227SGreg Roach */ 8815d603e7SGreg Roach public function createCensusAssistant(Individual $individual) { 8934cd602eSGreg Roach return View::make('modules/census-assistant', [ 9034cd602eSGreg Roach 'individual' => $individual, 9134cd602eSGreg Roach ]); 9215d603e7SGreg Roach } 9315d603e7SGreg Roach 9415d603e7SGreg Roach /** 9515d603e7SGreg Roach * @param Individual $individual 9660bc3e3fSGreg Roach * @param string $fact_id 9715d603e7SGreg Roach * @param string $newged 9860bc3e3fSGreg Roach * @param bool $keep_chan 9915d603e7SGreg Roach * 10015d603e7SGreg Roach * @return string 10115d603e7SGreg Roach */ 10215d603e7SGreg Roach public function updateCensusAssistant(Individual $individual, $fact_id, $newged, $keep_chan) { 10315d603e7SGreg Roach $ca_title = Filter::post('ca_title'); 10415d603e7SGreg Roach $ca_place = Filter::post('ca_place'); 10515d603e7SGreg Roach $ca_citation = Filter::post('ca_citation'); 10615d603e7SGreg Roach $ca_individuals = Filter::postArray('ca_individuals'); 10715d603e7SGreg Roach $ca_notes = Filter::post('ca_notes'); 10815d603e7SGreg Roach $ca_census = Filter::post('ca_census', 'Fisharebest\\\\Webtrees\\\\Census\\\\CensusOf[A-Za-z0-9]+'); 10915d603e7SGreg Roach 11015d603e7SGreg Roach if ($ca_census !== '' && !empty($ca_individuals)) { 11115d603e7SGreg Roach $census = new $ca_census; 11215d603e7SGreg Roach 11315d603e7SGreg Roach $note_text = $this->createNoteText($census, $ca_title, $ca_place, $ca_citation, $ca_individuals, $ca_notes); 11415d603e7SGreg Roach $note_gedcom = '0 @new@ NOTE ' . str_replace("\n", "\n1 CONT ", $note_text); 11515d603e7SGreg Roach $note = $individual->getTree()->createRecord($note_gedcom); 11615d603e7SGreg Roach 11715d603e7SGreg Roach $newged .= "\n2 NOTE @" . $note->getXref() . '@'; 11815d603e7SGreg Roach 11915d603e7SGreg Roach // Add the census fact to the rest of the household 12015d603e7SGreg Roach foreach (array_keys($ca_individuals) as $xref) { 12115d603e7SGreg Roach if ($xref !== $individual->getXref()) { 12215d603e7SGreg Roach Individual::getInstance($xref, $individual->getTree()) 12315d603e7SGreg Roach ->updateFact($fact_id, $newged, !$keep_chan); 12415d603e7SGreg Roach } 12515d603e7SGreg Roach } 12615d603e7SGreg Roach } 12715d603e7SGreg Roach 12815d603e7SGreg Roach return $newged; 12915d603e7SGreg Roach } 13015d603e7SGreg Roach 13115d603e7SGreg Roach /** 13215d603e7SGreg Roach * @param CensusInterface $census 13315d603e7SGreg Roach * @param string $ca_title 13415d603e7SGreg Roach * @param string $ca_place 13515d603e7SGreg Roach * @param string $ca_citation 13615d603e7SGreg Roach * @param string[][] $ca_individuals 13715d603e7SGreg Roach * @param string $ca_notes 13815d603e7SGreg Roach * 13915d603e7SGreg Roach * @return string 14015d603e7SGreg Roach */ 14115d603e7SGreg Roach private function createNoteText(CensusInterface $census, $ca_title, $ca_place, $ca_citation, $ca_individuals, $ca_notes) { 142*0d46ec71SGreg Roach $text = $ca_title . "\n" . $ca_citation . "\n" . $ca_place . "\n\n"; 14315d603e7SGreg Roach 14415d603e7SGreg Roach foreach ($census->columns() as $n => $column) { 145*0d46ec71SGreg Roach if ($n === 0) { 146*0d46ec71SGreg Roach $text .= "\n"; 147*0d46ec71SGreg Roach } else { 14815d603e7SGreg Roach $text .= '|'; 14915d603e7SGreg Roach } 150*0d46ec71SGreg Roach $text .= $column->abbreviation(); 151*0d46ec71SGreg Roach } 152*0d46ec71SGreg Roach 153*0d46ec71SGreg Roach foreach ($census->columns() as $n => $column) { 154*0d46ec71SGreg Roach if ($n === 0) { 155*0d46ec71SGreg Roach $text .= "\n"; 156*0d46ec71SGreg Roach } else { 157*0d46ec71SGreg Roach $text .= '|'; 158*0d46ec71SGreg Roach } 159*0d46ec71SGreg Roach $text .= '-----'; 16015d603e7SGreg Roach } 16115d603e7SGreg Roach 16215d603e7SGreg Roach foreach ($ca_individuals as $xref => $columns) { 16315d603e7SGreg Roach $text .= "\n" . implode('|', $columns); 16415d603e7SGreg Roach } 16515d603e7SGreg Roach 166*0d46ec71SGreg Roach return $text . "\n\n" . $ca_notes; 16740990b78SGreg Roach } 16840990b78SGreg Roach 16940990b78SGreg Roach /** 17076692c8bSGreg Roach * Find a media object. 17140990b78SGreg Roach */ 172764a01d9SGreg Roach private static function mediaFind() { 1738c2e8227SGreg Roach global $WT_TREE; 1748c2e8227SGreg Roach 1758c2e8227SGreg Roach $controller = new SimpleController; 1768c2e8227SGreg Roach $filter = Filter::get('filter'); 1778c2e8227SGreg Roach $multiple = Filter::getBool('multiple'); 1788c2e8227SGreg Roach 1798c2e8227SGreg Roach $controller 1808c2e8227SGreg Roach ->setPageTitle(I18N::translate('Find an individual')) 1818c2e8227SGreg Roach ->pageHeader(); 1828c2e8227SGreg Roach 1838c2e8227SGreg Roach ?> 18499f222b3SGreg Roach <script> 1858c2e8227SGreg Roach function pasterow(id, name, gend, yob, age, bpl) { 1868c2e8227SGreg Roach window.opener.opener.insertRowToTable(id, name, '', gend, '', yob, age, 'Y', '', bpl); 1878c2e8227SGreg Roach } 1888c2e8227SGreg Roach 1898c2e8227SGreg Roach function pasteid(id, name, thumb) { 1908c2e8227SGreg Roach if (thumb) { 1918c2e8227SGreg Roach window.opener.paste_id(id, name, thumb); 19215d603e7SGreg Roach <?php if (!$multiple) { 19315d603e7SGreg Roach echo 'window.close();'; 19415d603e7SGreg Roach } ?> 1958c2e8227SGreg Roach } else { 1968c2e8227SGreg Roach // GEDFact_assistant ======================== 1978c2e8227SGreg Roach if (window.opener.document.getElementById('addlinkQueue')) { 1988c2e8227SGreg Roach window.opener.insertRowToTable(id, name); 1998c2e8227SGreg Roach } 2008c2e8227SGreg Roach window.opener.paste_id(id); 2018c2e8227SGreg Roach if (window.opener.pastename) { 2028c2e8227SGreg Roach window.opener.pastename(name); 2038c2e8227SGreg Roach } 20415d603e7SGreg Roach <?php if (!$multiple) { 20515d603e7SGreg Roach echo 'window.close();'; 20615d603e7SGreg Roach } ?> 2078c2e8227SGreg Roach } 2088c2e8227SGreg Roach } 20915d603e7SGreg Roach 2108c2e8227SGreg Roach function checknames(frm) { 2116fde90caSGreg Roach var button = ''; 2128c2e8227SGreg Roach if (document.forms[0].subclick) { 2138c2e8227SGreg Roach button = document.forms[0].subclick.value; 2148c2e8227SGreg Roach } 21515d603e7SGreg Roach if (frm.filter.value.length < 2 && button !== 'all') { 21615d603e7SGreg Roach alert('<?= I18N::translate('Please enter more than one character.') ?>'); 2178c2e8227SGreg Roach frm.filter.focus(); 2188c2e8227SGreg Roach return false; 2198c2e8227SGreg Roach } 2206fde90caSGreg Roach if (button === 'all') { 22115d603e7SGreg Roach frm.filter.value = ''; 2228c2e8227SGreg Roach } 2238c2e8227SGreg Roach return true; 2248c2e8227SGreg Roach } 22599f222b3SGreg Roach </script> 2268c2e8227SGreg Roach 22799f222b3SGreg Roach <?php 228a86dd8b1SGreg Roach echo '<div>'; 2294c621133SGreg Roach echo '<table class="list_table width90" border="0">'; 230d20fc238SGreg Roach echo '<tr><td style="padding: 10px;" class="width90">'; // start column for find text header 2318c2e8227SGreg Roach echo $controller->getPageTitle(); 2324c621133SGreg Roach echo '</td>'; 2334c621133SGreg Roach echo '</tr>'; 2344c621133SGreg Roach echo '</table>'; 2354c621133SGreg Roach echo '<br>'; 2368c2e8227SGreg Roach echo '<button onclick="window.close();">', I18N::translate('close'), '</button>'; 2374c621133SGreg Roach echo '<br>'; 2388c2e8227SGreg Roach 2398c2e8227SGreg Roach $filter = trim($filter); 2408c2e8227SGreg Roach $filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter)); 2414c621133SGreg Roach echo '<table class="tabs_table width90"><tr>'; 24213abd6f3SGreg Roach $myindilist = FunctionsDb::searchIndividualNames($filter_array, [$WT_TREE]); 2438c2e8227SGreg Roach if ($myindilist) { 2444c621133SGreg Roach echo '<td class="list_value_wrap"><ul>'; 2450e62c4b8SGreg Roach usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare'); 2468c2e8227SGreg Roach foreach ($myindilist as $indi) { 247cc5ab399SGreg Roach $nam = Html::escape($indi->getFullName()); 2488c2e8227SGreg Roach echo "<li><a href=\"#\" onclick=\"pasterow( 2498c2e8227SGreg Roach '" . $indi->getXref() . "' , 2508c2e8227SGreg Roach '" . $nam . "' , 2518c2e8227SGreg Roach '" . $indi->getSex() . "' , 2527820e4d7SGreg Roach '" . $indi->getBirthYear() . "' , 2537820e4d7SGreg Roach '" . (1901 - $indi->getBirthYear()) . "' , 2547820e4d7SGreg Roach '" . $indi->getBirthPlace() . "'); return false;\"> 2557a6ee1acSGreg Roach <b>" . $indi->getFullName() . '</b> '; 2568c2e8227SGreg Roach 257564ae2d7SGreg Roach $born = I18N::translate('Birth'); 2587a6ee1acSGreg Roach echo '</span><br><span class="list_item">', $born, ' ', $indi->getBirthYear(), ' ', $indi->getBirthPlace(), '</span></a></li>'; 2597a6ee1acSGreg Roach echo '<hr>'; 2608c2e8227SGreg Roach } 2618c2e8227SGreg Roach echo '</ul></td></tr><tr><td class="list_label">', I18N::translate('Total individuals: %s', count($myindilist)), '</tr></td>'; 2628c2e8227SGreg Roach } else { 2637a6ee1acSGreg Roach echo '<td class="list_value_wrap">'; 2648c2e8227SGreg Roach echo I18N::translate('No results found.'); 2657a6ee1acSGreg Roach echo '</td></tr>'; 2668c2e8227SGreg Roach } 2677a6ee1acSGreg Roach echo '</table>'; 2688c2e8227SGreg Roach echo '</div>'; 2698c2e8227SGreg Roach } 2708c2e8227SGreg Roach 2718c2e8227SGreg Roach /** 27276692c8bSGreg Roach * Search for a media object. 2738c2e8227SGreg Roach */ 274764a01d9SGreg Roach private static function mediaQuery() { 27524ec66ceSGreg Roach global $WT_TREE; 27624ec66ceSGreg Roach 2778c2e8227SGreg Roach $iid2 = Filter::get('iid', WT_REGEX_XREF); 2788c2e8227SGreg Roach 2798c2e8227SGreg Roach $controller = new SimpleController; 2808c2e8227SGreg Roach $controller 2818c2e8227SGreg Roach ->setPageTitle(I18N::translate('Link to an existing media object')) 2828c2e8227SGreg Roach ->pageHeader(); 2838c2e8227SGreg Roach 28424ec66ceSGreg Roach $record = GedcomRecord::getInstance($iid2, $WT_TREE); 2858c2e8227SGreg Roach if ($record) { 2868c2e8227SGreg Roach $headjs = ''; 2878c2e8227SGreg Roach if ($record instanceof Family) { 2888c2e8227SGreg Roach if ($record->getHusband()) { 2898c2e8227SGreg Roach $headjs = $record->getHusband()->getXref(); 2908c2e8227SGreg Roach } elseif ($record->getWife()) { 2918c2e8227SGreg Roach $headjs = $record->getWife()->getXref(); 2928c2e8227SGreg Roach } 2938c2e8227SGreg Roach } 2948c2e8227SGreg Roach ?> 2958c2e8227SGreg Roach <script> 2968c2e8227SGreg Roach function insertId() { 2978c2e8227SGreg Roach if (window.opener.document.getElementById('addlinkQueue')) { 2988c2e8227SGreg Roach // alert('Please move this alert window and examine the contents of the pop-up window, then click OK') 299564ae2d7SGreg Roach window.opener.insertRowToTable('<?= $record->getXref() ?>', '<?= htmlspecialchars($record->getFullName()) ?>', '<?= $headjs ?>'); 3008c2e8227SGreg Roach window.close(); 3018c2e8227SGreg Roach } 3028c2e8227SGreg Roach } 3038c2e8227SGreg Roach </script> 3048c2e8227SGreg Roach <?php 3058c2e8227SGreg Roach } else { 3068c2e8227SGreg Roach ?> 3078c2e8227SGreg Roach <script> 3088c2e8227SGreg Roach function insertId() { 309564ae2d7SGreg Roach window.opener.alert('<?= $iid2 ?> - <?= I18N::translate('Not a valid individual, family, or source ID') ?>'); 3108c2e8227SGreg Roach window.close(); 3118c2e8227SGreg Roach } 3128c2e8227SGreg Roach </script> 3138c2e8227SGreg Roach <?php 3148c2e8227SGreg Roach } 3158c2e8227SGreg Roach ?> 3168c2e8227SGreg Roach <script>window.onLoad = insertId();</script> 3178c2e8227SGreg Roach <?php 3188c2e8227SGreg Roach } 3198c2e8227SGreg Roach 3208c2e8227SGreg Roach /** 3218c2e8227SGreg Roach * Convert custom markup into HTML 3228c2e8227SGreg Roach * 3238c2e8227SGreg Roach * @param Note $note 3248c2e8227SGreg Roach * 3258c2e8227SGreg Roach * @return string 3268c2e8227SGreg Roach */ 3278c2e8227SGreg Roach public static function formatCensusNote(Note $note) { 32814c3d3fbSGreg Roach if (preg_match('/(.*)((?:\n.*)*)\n\.start_formatted_area\.\n(.+)\n(.+(?:\n.+)*)\n.end_formatted_area\.((?:\n.*)*)/', $note->getNote(), $match)) { 3298c2e8227SGreg Roach // This looks like a census-assistant shared note 330cc5ab399SGreg Roach $title = Html::escape($match[1]); 331cc5ab399SGreg Roach $preamble = Html::escape($match[2]); 332cc5ab399SGreg Roach $header = Html::escape($match[3]); 333cc5ab399SGreg Roach $data = Html::escape($match[4]); 334cc5ab399SGreg Roach $postamble = Html::escape($match[5]); 3358c2e8227SGreg Roach 336dc46b574SDavid Drury // Get the column headers for the census to which this note refers 337dc46b574SDavid Drury // requires the fact place & date to match the specific census 338dc46b574SDavid Drury // censusPlace() (Soundex match) and censusDate() functions 33913abd6f3SGreg Roach $fmt_headers = []; 34015d603e7SGreg Roach /** @var GedcomRecord[] $linkedRecords */ 341dc46b574SDavid Drury $linkedRecords = array_merge($note->linkedIndividuals('NOTE'), $note->linkedFamilies('NOTE')); 342dc46b574SDavid Drury $firstRecord = array_shift($linkedRecords); 343dc46b574SDavid Drury if ($firstRecord) { 344dc46b574SDavid Drury $countryCode = ''; 345dc46b574SDavid Drury $date = ''; 346dc46b574SDavid Drury foreach ($firstRecord->getFacts('CENS') as $fact) { 347dc46b574SDavid Drury if (trim($fact->getAttribute('NOTE'), '@') === $note->getXref()) { 348dc46b574SDavid Drury $date = $fact->getAttribute('DATE'); 349dc46b574SDavid Drury $place = explode(',', strip_tags($fact->getPlace()->getFullName())); 350dc46b574SDavid Drury $countryCode = Soundex::daitchMokotoff(array_pop($place)); 351dc46b574SDavid Drury break; 352dc46b574SDavid Drury } 3538c2e8227SGreg Roach } 3548c2e8227SGreg Roach 355dc46b574SDavid Drury foreach (Census::allCensusPlaces() as $censusPlace) { 356dc46b574SDavid Drury if (Soundex::compare($countryCode, Soundex::daitchMokotoff($censusPlace->censusPlace()))) { 357dc46b574SDavid Drury foreach ($censusPlace->allCensusDates() as $census) { 358dc46b574SDavid Drury if ($census->censusDate() == $date) { 359dc46b574SDavid Drury foreach ($census->columns() as $column) { 360dc46b574SDavid Drury $abbrev = $column->abbreviation(); 361dc46b574SDavid Drury if ($abbrev) { 362dc46b574SDavid Drury $description = $column->title() ? $column->title() : I18N::translate('Description unavailable'); 363dc46b574SDavid Drury $fmt_headers[$abbrev] = '<span title="' . $description . '">' . $abbrev . '</span>'; 364dc46b574SDavid Drury } 365dc46b574SDavid Drury } 366dc46b574SDavid Drury break 2; 367dc46b574SDavid Drury } 368dc46b574SDavid Drury } 369dc46b574SDavid Drury } 370dc46b574SDavid Drury } 371dc46b574SDavid Drury } 372dc46b574SDavid Drury // Substitute header labels and format as HTML 3738c2e8227SGreg Roach $thead = '<tr><th>' . strtr(str_replace('|', '</th><th>', $header), $fmt_headers) . '</th></tr>'; 374ad51e0bbSGreg Roach $thead = str_replace('.b.', '', $thead); 3758c2e8227SGreg Roach 3768c2e8227SGreg Roach // Format data as HTML 3778c2e8227SGreg Roach $tbody = ''; 37814c3d3fbSGreg Roach foreach (explode("\n", $data) as $row) { 3798c2e8227SGreg Roach $tbody .= '<tr>'; 3808c2e8227SGreg Roach foreach (explode('|', $row) as $column) { 3818c2e8227SGreg Roach $tbody .= '<td>' . $column . '</td>'; 3828c2e8227SGreg Roach } 3838c2e8227SGreg Roach $tbody .= '</tr>'; 3848c2e8227SGreg Roach } 3858c2e8227SGreg Roach 3868c2e8227SGreg Roach return 3878c2e8227SGreg Roach $title . "\n" . // The newline allows the framework to expand the details and turn the first line into a link 388673157b0SGreg Roach '<div class="markdown">' . 3898c2e8227SGreg Roach '<p>' . $preamble . '</p>' . 390dc46b574SDavid Drury '<table>' . 3918c2e8227SGreg Roach '<thead>' . $thead . '</thead>' . 3928c2e8227SGreg Roach '<tbody>' . $tbody . '</tbody>' . 3938c2e8227SGreg Roach '</table>' . 394dc46b574SDavid Drury '<p>' . $postamble . '</p>' . 395dc46b574SDavid Drury '</div>'; 3968c2e8227SGreg Roach } else { 3978c2e8227SGreg Roach // Not a census-assistant shared note - apply default formatting 39815d603e7SGreg Roach return Filter::formatText($note->getNote(), $note->getTree()); 3998c2e8227SGreg Roach } 4008c2e8227SGreg Roach } 40199f222b3SGreg Roach 40299f222b3SGreg Roach /** 403ad51e0bbSGreg Roach * Generate an HTML row of data for the census header 40452bc9faeSGreg Roach * Add prefix cell (store XREF and drag/drop) 40552bc9faeSGreg Roach * Add suffix cell (delete button) 40652bc9faeSGreg Roach * 407ad51e0bbSGreg Roach * @param CensusInterface $census 40899f222b3SGreg Roach * 409ad51e0bbSGreg Roach * @return string 41099f222b3SGreg Roach */ 411ad51e0bbSGreg Roach public static function censusTableHeader(CensusInterface $census) { 41252bc9faeSGreg Roach $html = ''; 413ad51e0bbSGreg Roach foreach ($census->columns() as $column) { 41415d603e7SGreg Roach $html .= '<th class="wt-census-assistant-field" title="' . $column->title() . '">' . $column->abbreviation() . '</th>'; 41599f222b3SGreg Roach } 41699f222b3SGreg Roach 41715d603e7SGreg Roach return '<tr class="wt-census-assistant-row"><th hidden></th>' . $html . '<th></th></tr>'; 418ad51e0bbSGreg Roach } 41999f222b3SGreg Roach 420ad51e0bbSGreg Roach /** 421ad51e0bbSGreg Roach * Generate an HTML row of data for the census 42252bc9faeSGreg Roach * Add prefix cell (store XREF and drag/drop) 42352bc9faeSGreg Roach * Add suffix cell (delete button) 42452bc9faeSGreg Roach * 425ad51e0bbSGreg Roach * @param CensusInterface $census 426ad51e0bbSGreg Roach * 427ad51e0bbSGreg Roach * @return string 428ad51e0bbSGreg Roach */ 429ad51e0bbSGreg Roach public static function censusTableEmptyRow(CensusInterface $census) { 43015d603e7SGreg Roach return '<tr class="wt-census-assistant-row"><td hidden></td>' . str_repeat('<td class="wt-census-assistant-field"><input type="text" class="form-control wt-census-assistant-form-control"></td>', count($census->columns())) . '<td><a class="icon-remove" href="#" title="' . I18N::translate('Remove') . '"></a></td></tr>'; 431ad51e0bbSGreg Roach } 43299f222b3SGreg Roach 433ad51e0bbSGreg Roach /** 434ad51e0bbSGreg Roach * Generate an HTML row of data for the census 43552bc9faeSGreg Roach * Add prefix cell (store XREF and drag/drop) 43652bc9faeSGreg Roach * Add suffix cell (delete button) 43752bc9faeSGreg Roach * 438ad51e0bbSGreg Roach * @param CensusInterface $census 439ad51e0bbSGreg Roach * @param Individual $individual 440ad51e0bbSGreg Roach * @param Individual $head 441ad51e0bbSGreg Roach * 442ad51e0bbSGreg Roach * @return string 443ad51e0bbSGreg Roach */ 44415d603e7SGreg Roach public static function censusTableRow(CensusInterface $census, Individual $individual, Individual $head) { 44515d603e7SGreg Roach $html = ''; 44615d603e7SGreg Roach foreach ($census->columns() as $column) { 44715d603e7SGreg Roach $html .= '<td class="wt-census-assistant-field"><input class="form-control wt-census-assistant-form-control" type="text" value="' . $column->generate($individual, $head) . '" name="ca_individuals[' . $individual->getXref() . '][]"></td>'; 44899f222b3SGreg Roach } 44999f222b3SGreg Roach 45015d603e7SGreg Roach return '<tr class="wt-census-assistant-row"><td class="wt-census-assistant-field" hidden>' . $individual->getXref() . '</td>' . $html . '<td class="wt-census-assistant-field"><a class="icon-remove" href="#" title="' . I18N::translate('Remove') . '"></a></td></tr>'; 45199f222b3SGreg Roach } 4528c2e8227SGreg Roach} 453