xref: /webtrees/app/Module/CensusAssistantModule.php (revision ad51e0bb9a7bb401eb57cbcefc4f840924a5bbaa)
18c2e8227SGreg Roach<?php
28c2e8227SGreg Roach/**
38c2e8227SGreg Roach * webtrees: online genealogy
48c2e8227SGreg Roach * Copyright (C) 2015 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
18*ad51e0bbSGreg Roachuse Fisharebest\Webtrees\Census\CensusInterface;
190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Controller\SimpleController;
204c00bbb9SGreg Roachuse Fisharebest\Webtrees\Date;
210e62c4b8SGreg Roachuse Fisharebest\Webtrees\Family;
220e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter;
23*ad51e0bbSGreg 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;
29*ad51e0bbSGreg Roachuse Fisharebest\Webtrees\Menu;
300e62c4b8SGreg Roachuse Fisharebest\Webtrees\Note;
318c2e8227SGreg Roach
328c2e8227SGreg Roach/**
338c2e8227SGreg Roach * Class CensusAssistantModule
348c2e8227SGreg Roach */
3515834aaeSGreg Roachclass CensusAssistantModule extends AbstractModule {
368c2e8227SGreg Roach	/** {@inheritdoc} */
378c2e8227SGreg Roach	public function getTitle() {
388c2e8227SGreg Roach		return /* I18N: Name of a module */ I18N::translate('Census assistant');
398c2e8227SGreg Roach	}
408c2e8227SGreg Roach
418c2e8227SGreg Roach	/** {@inheritdoc} */
428c2e8227SGreg Roach	public function getDescription() {
438c2e8227SGreg Roach		return /* I18N: Description of the “Census assistant” module */ I18N::translate('An alternative way to enter census transcripts and link them to individuals.');
448c2e8227SGreg Roach	}
458c2e8227SGreg Roach
4676692c8bSGreg Roach	/**
4776692c8bSGreg Roach	 * This is a general purpose hook, allowing modules to respond to routes
4876692c8bSGreg Roach	 * of the form module.php?mod=FOO&mod_action=BAR
4976692c8bSGreg Roach	 *
5076692c8bSGreg Roach	 * @param string $mod_action
5176692c8bSGreg Roach	 */
528c2e8227SGreg Roach	public function modAction($mod_action) {
538c2e8227SGreg Roach		switch ($mod_action) {
5440990b78SGreg Roach		case 'census_find':
5540990b78SGreg Roach			self::censusFind();
568c2e8227SGreg Roach			break;
5740990b78SGreg Roach		case 'media_find':
58764a01d9SGreg Roach			self::mediaFind();
598c2e8227SGreg Roach			break;
608c2e8227SGreg Roach		case 'media_query_3a':
61764a01d9SGreg Roach			self::mediaQuery();
628c2e8227SGreg Roach			break;
638c2e8227SGreg Roach		default:
648c2e8227SGreg Roach			http_response_code(404);
658c2e8227SGreg Roach		}
668c2e8227SGreg Roach	}
678c2e8227SGreg Roach
688c2e8227SGreg Roach	/**
6976692c8bSGreg Roach	 * Find an individual.
708c2e8227SGreg Roach	 */
7140990b78SGreg Roach	private static function censusFind() {
7240990b78SGreg Roach		global $WT_TREE;
7340990b78SGreg Roach
7440990b78SGreg Roach		$controller = new SimpleController;
7540990b78SGreg Roach
7640990b78SGreg Roach		$filter   = Filter::get('filter');
7740990b78SGreg Roach		$action   = Filter::get('action');
7840990b78SGreg Roach		$callback = Filter::get('callback');
7940990b78SGreg Roach		$multiple = Filter::getBool('multiple');
80*ad51e0bbSGreg Roach		$census   = Filter::get('census');
81*ad51e0bbSGreg Roach		$census   = new $census;
8240990b78SGreg Roach
8340990b78SGreg Roach		$controller
84*ad51e0bbSGreg Roach			->restrictAccess($census instanceof CensusInterface)
8540990b78SGreg Roach			->setPageTitle(I18N::translate('Find an individual'))
8640990b78SGreg Roach			->pageHeader();
8740990b78SGreg Roach
88*ad51e0bbSGreg Roach		echo '<table class="list_table width90" border="0">';
89*ad51e0bbSGreg Roach		echo '<tr><td style="padding: 10px;" valign="top" class="facts_label03 width90">';
9040990b78SGreg Roach		echo I18N::translate('Find an individual');
91*ad51e0bbSGreg Roach		echo '</td>';
92*ad51e0bbSGreg Roach		echo '</table>';
93*ad51e0bbSGreg Roach		echo '<br>';
9440990b78SGreg Roach
95*ad51e0bbSGreg Roach		if ($action == 'filter') {
9640990b78SGreg Roach			$filter       = trim($filter);
9740990b78SGreg Roach			$filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter));
9840990b78SGreg Roach
9940990b78SGreg Roach			// Output Individual for GEDFact Assistant ======================
100*ad51e0bbSGreg Roach			echo '<table class="list_table width90">';
1013d7a8a4cSGreg Roach			$myindilist = FunctionsDb::searchIndividualNames($filter_array, array($WT_TREE));
10240990b78SGreg Roach			if ($myindilist) {
103*ad51e0bbSGreg Roach				echo '<tr><td class="list_value_wrap"><ul>';
10440990b78SGreg Roach				usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare');
10540990b78SGreg Roach				foreach ($myindilist as $indi) {
106*ad51e0bbSGreg Roach					echo '<li>';
107*ad51e0bbSGreg Roach					echo '<a href="#" onclick="window.opener.appendCensusRow(\'' . Filter::escapeJs(CensusAssistantModule::censusTableRow($census, $indi, null)) . '\'); window.close();">';
108*ad51e0bbSGreg Roach					echo '<b>' . $indi->getFullName() . '</b>';
109*ad51e0bbSGreg Roach					echo '</a>';
110*ad51e0bbSGreg Roach					echo $indi->formatFirstMajorFact(WT_EVENTS_BIRT, 1);
111*ad51e0bbSGreg Roach					echo $indi->formatFirstMajorFact(WT_EVENTS_DEAT, 1);
112*ad51e0bbSGreg Roach					echo '<hr>';
113*ad51e0bbSGreg Roach					echo '</li>';
11440990b78SGreg Roach				}
11540990b78SGreg Roach				echo '</ul></td></tr>';
11640990b78SGreg Roach			} else {
117*ad51e0bbSGreg Roach				echo '<tr><td class="list_value_wrap">';
11840990b78SGreg Roach				echo I18N::translate('No results found.');
119*ad51e0bbSGreg Roach				echo '</td></tr>';
12040990b78SGreg Roach			}
121*ad51e0bbSGreg Roach			echo '<tr><td>';
12240990b78SGreg Roach			echo '<button onclick="window.close();">', I18N::translate('close'), '</button>';
123*ad51e0bbSGreg Roach			echo '</td></tr>';
124*ad51e0bbSGreg Roach			echo '</table>';
125*ad51e0bbSGreg Roach		}
12640990b78SGreg Roach	}
12740990b78SGreg Roach
12840990b78SGreg Roach	/**
12976692c8bSGreg Roach	 * Find a media object.
13040990b78SGreg Roach	 */
131764a01d9SGreg Roach	private static function mediaFind() {
1328c2e8227SGreg Roach		global $WT_TREE;
1338c2e8227SGreg Roach
1348c2e8227SGreg Roach		$controller = new SimpleController;
1358c2e8227SGreg Roach		$filter     = Filter::get('filter');
1368c2e8227SGreg Roach		$multiple   = Filter::getBool('multiple');
1378c2e8227SGreg Roach
1388c2e8227SGreg Roach		$controller
1398c2e8227SGreg Roach			->setPageTitle(I18N::translate('Find an individual'))
1408c2e8227SGreg Roach			->pageHeader();
1418c2e8227SGreg Roach
1428c2e8227SGreg Roach		?>
14399f222b3SGreg Roach		<script>
1448c2e8227SGreg Roach		function pasterow(id, name, gend, yob, age, bpl) {
1458c2e8227SGreg Roach			window.opener.opener.insertRowToTable(id, name, '', gend, '', yob, age, 'Y', '', bpl);
1468c2e8227SGreg Roach		}
1478c2e8227SGreg Roach
1488c2e8227SGreg Roach		function pasteid(id, name, thumb) {
1498c2e8227SGreg Roach			if (thumb) {
1508c2e8227SGreg Roach				window.opener.paste_id(id, name, thumb);
15199f222b3SGreg Roach				<?php if (!$multiple) { echo "window.close();"; } ?>
1528c2e8227SGreg Roach			} else {
1538c2e8227SGreg Roach			// GEDFact_assistant ========================
1548c2e8227SGreg Roach			if (window.opener.document.getElementById('addlinkQueue')) {
1558c2e8227SGreg Roach				window.opener.insertRowToTable(id, name);
1568c2e8227SGreg Roach			}
1578c2e8227SGreg Roach			window.opener.paste_id(id);
1588c2e8227SGreg Roach			if (window.opener.pastename) {
1598c2e8227SGreg Roach				window.opener.pastename(name);
1608c2e8227SGreg Roach			}
16199f222b3SGreg Roach			<?php if (!$multiple) { echo "window.close();"; } ?>
1628c2e8227SGreg Roach			}
1638c2e8227SGreg Roach		}
1648c2e8227SGreg Roach		function checknames(frm) {
1658c2e8227SGreg Roach			if (document.forms[0].subclick) {
1668c2e8227SGreg Roach				button = document.forms[0].subclick.value;
1678c2e8227SGreg Roach			} else {
1688c2e8227SGreg Roach				button = "";
1698c2e8227SGreg Roach			}
170*ad51e0bbSGreg Roach			if (frm.filter.value.length < 2 && button !== "all") {
17177e70a22SGreg Roach				alert("<?php echo I18N::translate('Please enter more than one character.'); ?>");
1728c2e8227SGreg Roach				frm.filter.focus();
1738c2e8227SGreg Roach				return false;
1748c2e8227SGreg Roach			}
1758c2e8227SGreg Roach			if (button=="all") {
1768c2e8227SGreg Roach				frm.filter.value = "";
1778c2e8227SGreg Roach			}
1788c2e8227SGreg Roach			return true;
1798c2e8227SGreg Roach		}
18099f222b3SGreg Roach		</script>
1818c2e8227SGreg Roach
18299f222b3SGreg Roach		<?php
1838c2e8227SGreg Roach		echo "<div align=\"center\">";
1848c2e8227SGreg Roach		echo "<table class=\"list_table width90\" border=\"0\">";
1858c2e8227SGreg Roach		echo "<tr><td style=\"padding: 10px;\" valign=\"top\" class=\"facts_label03 width90\">"; // start column for find text header
1868c2e8227SGreg Roach		echo $controller->getPageTitle();
1878c2e8227SGreg Roach		echo "</td>";
1888c2e8227SGreg Roach		echo "</tr>";
1898c2e8227SGreg Roach		echo "</table>";
1908c2e8227SGreg Roach		echo "<br>";
1918c2e8227SGreg Roach		echo '<button onclick="window.close();">', I18N::translate('close'), '</button>';
1928c2e8227SGreg Roach		echo "<br>";
1938c2e8227SGreg Roach
1948c2e8227SGreg Roach		$filter       = trim($filter);
1958c2e8227SGreg Roach		$filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter));
1968c2e8227SGreg Roach		echo "<table class=\"tabs_table width90\"><tr>";
1973d7a8a4cSGreg Roach		$myindilist = FunctionsDb::searchIndividualNames($filter_array, array($WT_TREE));
1988c2e8227SGreg Roach		if ($myindilist) {
1998c2e8227SGreg Roach			echo "<td class=\"list_value_wrap\"><ul>";
2000e62c4b8SGreg Roach			usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare');
2018c2e8227SGreg Roach			foreach ($myindilist as $indi) {
2028c2e8227SGreg Roach				$nam = Filter::escapeHtml($indi->getFullName());
2038c2e8227SGreg Roach				echo "<li><a href=\"#\" onclick=\"pasterow(
2048c2e8227SGreg Roach					'" . $indi->getXref() . "' ,
2058c2e8227SGreg Roach					'" . $nam . "' ,
2068c2e8227SGreg Roach					'" . $indi->getSex() . "' ,
2078c2e8227SGreg Roach					'" . $indi->getbirthyear() . "' ,
2088c2e8227SGreg Roach					'" . (1901 - $indi->getbirthyear()) . "' ,
2098c2e8227SGreg Roach					'" . $indi->getbirthplace() . "'); return false;\">
2108c2e8227SGreg Roach					<b>" . $indi->getFullName() . "</b>&nbsp;&nbsp;&nbsp;";
2118c2e8227SGreg Roach
212764a01d9SGreg Roach				$born = GedcomTag::getLabel('BIRT');
2138c2e8227SGreg Roach				echo "</span><br><span class=\"list_item\">", $born, " ", $indi->getbirthyear(), "&nbsp;&nbsp;&nbsp;", $indi->getbirthplace(), "</span></a></li>";
2148c2e8227SGreg Roach				echo "<hr>";
2158c2e8227SGreg Roach			}
2168c2e8227SGreg Roach			echo '</ul></td></tr><tr><td class="list_label">', I18N::translate('Total individuals: %s', count($myindilist)), '</tr></td>';
2178c2e8227SGreg Roach		} else {
2188c2e8227SGreg Roach			echo "<td class=\"list_value_wrap\">";
2198c2e8227SGreg Roach			echo I18N::translate('No results found.');
2208c2e8227SGreg Roach			echo "</td></tr>";
2218c2e8227SGreg Roach		}
2228c2e8227SGreg Roach		echo "</table>";
2238c2e8227SGreg Roach		echo '</div>';
2248c2e8227SGreg Roach	}
2258c2e8227SGreg Roach
2268c2e8227SGreg Roach	/**
22776692c8bSGreg Roach	 * Search for a media object.
2288c2e8227SGreg Roach	 */
229764a01d9SGreg Roach	private static function mediaQuery() {
23024ec66ceSGreg Roach		global $WT_TREE;
23124ec66ceSGreg Roach
2328c2e8227SGreg Roach		$iid2 = Filter::get('iid', WT_REGEX_XREF);
2338c2e8227SGreg Roach
2348c2e8227SGreg Roach		$controller = new SimpleController;
2358c2e8227SGreg Roach		$controller
2368c2e8227SGreg Roach			->setPageTitle(I18N::translate('Link to an existing media object'))
2378c2e8227SGreg Roach			->pageHeader();
2388c2e8227SGreg Roach
23924ec66ceSGreg Roach		$record = GedcomRecord::getInstance($iid2, $WT_TREE);
2408c2e8227SGreg Roach		if ($record) {
2418c2e8227SGreg Roach			$headjs = '';
2428c2e8227SGreg Roach			if ($record instanceof Family) {
2438c2e8227SGreg Roach				if ($record->getHusband()) {
2448c2e8227SGreg Roach					$headjs = $record->getHusband()->getXref();
2458c2e8227SGreg Roach				} elseif ($record->getWife()) {
2468c2e8227SGreg Roach					$headjs = $record->getWife()->getXref();
2478c2e8227SGreg Roach				}
2488c2e8227SGreg Roach			}
2498c2e8227SGreg Roach			?>
2508c2e8227SGreg Roach			<script>
2518c2e8227SGreg Roach				function insertId() {
2528c2e8227SGreg Roach					if (window.opener.document.getElementById('addlinkQueue')) {
2538c2e8227SGreg Roach						// alert('Please move this alert window and examine the contents of the pop-up window, then click OK')
2548c2e8227SGreg Roach						window.opener.insertRowToTable('<?php echo $record->getXref(); ?>', '<?php echo htmlSpecialChars($record->getFullName()); ?>', '<?php echo $headjs; ?>');
2558c2e8227SGreg Roach						window.close();
2568c2e8227SGreg Roach					}
2578c2e8227SGreg Roach				}
2588c2e8227SGreg Roach			</script>
2598c2e8227SGreg Roach			<?php
2608c2e8227SGreg Roach		} else {
2618c2e8227SGreg Roach			?>
2628c2e8227SGreg Roach			<script>
2638c2e8227SGreg Roach				function insertId() {
26477e70a22SGreg Roach					window.opener.alert('<?php echo $iid2; ?> - <?php echo I18N::translate('Not a valid individual, family, or source ID'); ?>');
2658c2e8227SGreg Roach					window.close();
2668c2e8227SGreg Roach				}
2678c2e8227SGreg Roach			</script>
2688c2e8227SGreg Roach			<?php
2698c2e8227SGreg Roach		}
2708c2e8227SGreg Roach		?>
2718c2e8227SGreg Roach		<script>window.onLoad = insertId();</script>
2728c2e8227SGreg Roach		<?php
2738c2e8227SGreg Roach	}
2748c2e8227SGreg Roach
2758c2e8227SGreg Roach	/**
2768c2e8227SGreg Roach	 * Convert custom markup into HTML
2778c2e8227SGreg Roach	 *
2788c2e8227SGreg Roach	 * @param Note $note
2798c2e8227SGreg Roach	 *
2808c2e8227SGreg Roach	 * @return string
2818c2e8227SGreg Roach	 */
2828c2e8227SGreg Roach	public static function formatCensusNote(Note $note) {
2838c2e8227SGreg Roach		global $WT_TREE;
2848c2e8227SGreg Roach
2858c2e8227SGreg Roach		$headers = array(
2868c2e8227SGreg Roach			'AgM'        => 'Age at first marriage',
2878c2e8227SGreg Roach			'Age'        => 'Age at last birthday',
2888c2e8227SGreg Roach			'Assets'     => 'Assets = Owned,Rented - Value,Rent - Radio - Farm',
2898c2e8227SGreg Roach			'BIC'        => 'Born in County',
2908c2e8227SGreg Roach			'BOE'        => 'Born outside England',
2918c2e8227SGreg Roach			'BP'         => 'Birthplace - (Chapman format)',
2928c2e8227SGreg Roach			'Birthplace' => 'Birthplace (Full format)',
2938c2e8227SGreg Roach			'Bmth'       => 'Month of birth - If born within Census year',
2948c2e8227SGreg Roach			'ChB'        => 'Children born alive',
2958c2e8227SGreg Roach			'ChD'        => 'Children who have died',
2968c2e8227SGreg Roach			'ChL'        => 'Children still living',
2978c2e8227SGreg Roach			'DOB'        => 'Date of birth',
2988c2e8227SGreg Roach			'Edu'        => 'Education - At School, Can Read, Can Write', // or "Cannot Read, Cannot Write" ??
2998c2e8227SGreg Roach			'EmD'        => 'Employed?',
3008c2e8227SGreg Roach			'EmN'        => 'Unemployed?',
3018c2e8227SGreg Roach			'EmR'        => 'Employer?',
3028c2e8227SGreg Roach			'Employ'     => 'Employment',
3038c2e8227SGreg Roach			'Eng?'       => 'English spoken?',
3048c2e8227SGreg Roach			'EngL'       => 'English spoken?, if not, Native Language',
3058c2e8227SGreg Roach			'FBP'        => 'Father’s Birthplace - (Chapman format)',
3068c2e8227SGreg Roach			'Health'     => 'Health - 1.Blind, 2.Deaf & Dumb, 3.Idiotic, 4.Insane, 5.Disabled etc',
3078c2e8227SGreg Roach			'Home'       => 'Home Ownership - Owned/Rented-Free/Mortgaged-Farm/House-Farm Schedule number',
3088c2e8227SGreg Roach			'Industry'   => 'Industry',
3098c2e8227SGreg Roach			'Infirm'     => 'Infirmities - 1. Deaf & Dumb, 2. Blind, 3. Lunatic, 4. Imbecile/feeble-minded',
3108c2e8227SGreg Roach			'Lang'       => 'If Foreign Born - Native Language',
3118c2e8227SGreg Roach			'MBP'        => 'Mother’s Birthplace - (Chapman format)',
3128c2e8227SGreg Roach			'MC'         => 'Marital Condition - Married, Single, Unmarried, Widowed or Divorced',
3138c2e8227SGreg Roach			'Mmth'       => 'Month of marriage - If married during Census Year',
3148c2e8227SGreg Roach			'MnsE'       => 'Months employed during Census Year',
3158c2e8227SGreg Roach			'MnsU'       => 'Months unemployed during Census Year',
3168c2e8227SGreg Roach			'N/A'        => 'If Foreign Born - Naturalized, Alien',
3178c2e8227SGreg Roach			'NL'         => 'If Foreign Born - Native Language',
3188c2e8227SGreg Roach			'Name'       => 'Full Name or Married name if married',
3198c2e8227SGreg Roach			'Occupation' => 'Occupation',
3208c2e8227SGreg Roach			'Par'        => 'Parentage - Father if foreign born, Mother if foreign born',
3218c2e8227SGreg Roach			'Race'       => 'Race or Color - Black, White, Mulatto, Asian, Indian, Chinese etc',
3228c2e8227SGreg Roach			'Relation'   => 'Relationship to Head of Household',
3238c2e8227SGreg Roach			'Sex'        => 'Male or Female',
3248c2e8227SGreg Roach			'Situ'       => 'Situation - Disease, Infirmity, Convict, Pauper etc',
3258c2e8227SGreg Roach			'Ten'        => 'Tenure - Owned/Rented, (if owned)Free/Morgaged',
3268c2e8227SGreg Roach			'Vet'        => 'War Veteran?',
3278c2e8227SGreg Roach			'WH'         => 'Working at Home?',
3288c2e8227SGreg Roach			'War'        => 'War or Expedition',
3298c2e8227SGreg Roach			'WksU'       => 'Weeks unemployed during Census Year',
3308c2e8227SGreg Roach			'YOI'        => 'If Foreign Born - Year of immigration',
3318c2e8227SGreg Roach			'YON'        => 'If Foreign Born - Year of naturalization',
3328c2e8227SGreg Roach			'YUS'        => 'If Foreign Born - Years in the USA',
3338c2e8227SGreg Roach			'YrsM'       => 'Years Married, or Y if married in Census Year',
3348c2e8227SGreg Roach		);
3358c2e8227SGreg Roach
3368c2e8227SGreg Roach		if (preg_match('/(.*)((?:\n.*)*)\n\.start_formatted_area\.\n(.*)((?:\n.*)*)\n.end_formatted_area\.((?:\n.*)*)/', $note->getNote(), $match)) {
3378c2e8227SGreg Roach			// This looks like a census-assistant shared note
3388c2e8227SGreg Roach			$title     = Filter::escapeHtml($match[1]);
3398c2e8227SGreg Roach			$preamble  = Filter::escapeHtml($match[2]);
3408c2e8227SGreg Roach			$header    = Filter::escapeHtml($match[3]);
3418c2e8227SGreg Roach			$data      = Filter::escapeHtml($match[4]);
3428c2e8227SGreg Roach			$postamble = Filter::escapeHtml($match[5]);
3438c2e8227SGreg Roach
3448c2e8227SGreg Roach			$fmt_headers = array();
3458c2e8227SGreg Roach			foreach ($headers as $key => $value) {
346*ad51e0bbSGreg Roach				$fmt_headers[$key] = '<span title="' . Filter::escapeHtml($value) . '">' . $key . '</span>';
3478c2e8227SGreg Roach			}
3488c2e8227SGreg Roach
3498c2e8227SGreg Roach			// Substitue header labels and format as HTML
3508c2e8227SGreg Roach			$thead = '<tr><th>' . strtr(str_replace('|', '</th><th>', $header), $fmt_headers) . '</th></tr>';
351*ad51e0bbSGreg Roach			$thead = str_replace('.b.', '', $thead);
3528c2e8227SGreg Roach
3538c2e8227SGreg Roach			// Format data as HTML
3548c2e8227SGreg Roach			$tbody = '';
3558c2e8227SGreg Roach			foreach (explode("\n", $data) as $row) {
3568c2e8227SGreg Roach				$tbody .= '<tr>';
3578c2e8227SGreg Roach				foreach (explode('|', $row) as $column) {
3588c2e8227SGreg Roach					$tbody .= '<td>' . $column . '</td>';
3598c2e8227SGreg Roach				}
3608c2e8227SGreg Roach				$tbody .= '</tr>';
3618c2e8227SGreg Roach			}
3628c2e8227SGreg Roach
3638c2e8227SGreg Roach			return
3648c2e8227SGreg Roach				$title . "\n" . // The newline allows the framework to expand the details and turn the first line into a link
3658c2e8227SGreg Roach				'<p>' . $preamble . '</p>' .
3668c2e8227SGreg Roach				'<table class="table-census-assistant">' .
3678c2e8227SGreg Roach				'<thead>' . $thead . '</thead>' .
3688c2e8227SGreg Roach				'<tbody>' . $tbody . '</tbody>' .
3698c2e8227SGreg Roach				'</table>' .
3708c2e8227SGreg Roach				'<p>' . $postamble . '</p>';
3718c2e8227SGreg Roach		} else {
3728c2e8227SGreg Roach			// Not a census-assistant shared note - apply default formatting
3738c2e8227SGreg Roach			return Filter::formatText($note->getNote(), $WT_TREE);
3748c2e8227SGreg Roach		}
3758c2e8227SGreg Roach	}
37699f222b3SGreg Roach
37799f222b3SGreg Roach	/**
378*ad51e0bbSGreg Roach	 * Generate an HTML row of data for the census header
37999f222b3SGreg Roach	 *
380*ad51e0bbSGreg Roach	 * @param CensusInterface $census
38199f222b3SGreg Roach	 *
382*ad51e0bbSGreg Roach	 * @return string
38399f222b3SGreg Roach	 */
384*ad51e0bbSGreg Roach	public static function censusTableHeader(CensusInterface $census) {
385*ad51e0bbSGreg Roach		$html = '<th></th>'; // hidden column - used to save data
386*ad51e0bbSGreg Roach		foreach ($census->columns() as $column) {
387*ad51e0bbSGreg Roach			$html .= '<th title="' . $column->title() . '">' . $column->abbreviation() . '</th>';
38899f222b3SGreg Roach		}
38999f222b3SGreg Roach
390*ad51e0bbSGreg Roach		return '<tr>' . $html . '</tr>';
391*ad51e0bbSGreg Roach	}
39299f222b3SGreg Roach
393*ad51e0bbSGreg Roach	/**
394*ad51e0bbSGreg Roach	 * Generate an HTML row of data for the census
395*ad51e0bbSGreg Roach	 *
396*ad51e0bbSGreg Roach	 * @param CensusInterface $census
397*ad51e0bbSGreg Roach	 *
398*ad51e0bbSGreg Roach	 * @return string
399*ad51e0bbSGreg Roach	 */
400*ad51e0bbSGreg Roach	public static function censusTableEmptyRow(CensusInterface $census) {
401*ad51e0bbSGreg Roach		return '<tr><td></td>' . str_repeat('<td><input type="text"></td>', count($census->columns())) . '</tr>';
402*ad51e0bbSGreg Roach	}
40399f222b3SGreg Roach
404*ad51e0bbSGreg Roach/**
405*ad51e0bbSGreg Roach	 * Generate an HTML row of data for the census
406*ad51e0bbSGreg Roach	 *
407*ad51e0bbSGreg Roach	 * @param CensusInterface $census
408*ad51e0bbSGreg Roach	 * @param Individual      $individual
409*ad51e0bbSGreg Roach	 * @param Individual|null $head
410*ad51e0bbSGreg Roach	 *
411*ad51e0bbSGreg Roach	 * @return string
412*ad51e0bbSGreg Roach	 */
413*ad51e0bbSGreg Roach	public static function censusTableRow(CensusInterface $census, Individual $individual, Individual $head = null) {
414*ad51e0bbSGreg Roach		$html = '<td>' . $individual->getXref() . '</td>';
415*ad51e0bbSGreg Roach		foreach ($census->columns() as $column) {
416*ad51e0bbSGreg Roach			$html .= '<td><input type="text" value="' . $column->generate($individual, $head) . '"></td>';
417*ad51e0bbSGreg Roach		}
418*ad51e0bbSGreg Roach
419*ad51e0bbSGreg Roach		return '<tr>' . $html . '</tr>';
420*ad51e0bbSGreg Roach	}
421*ad51e0bbSGreg Roach
422*ad51e0bbSGreg Roach	/**
423*ad51e0bbSGreg Roach	 * Create a family on the census navigator.
424*ad51e0bbSGreg Roach	 *
425*ad51e0bbSGreg Roach	 * @param CensusInterface $census
426*ad51e0bbSGreg Roach	 * @param Family          $family
427*ad51e0bbSGreg Roach	 * @param Individual      $head
428*ad51e0bbSGreg Roach	 *
429*ad51e0bbSGreg Roach	 * @return string
430*ad51e0bbSGreg Roach	 */
431*ad51e0bbSGreg Roach	public static function censusNavigatorFamily(CensusInterface $census, Family $family, Individual $head) {
432*ad51e0bbSGreg Roach		$headImg2  = '<i class="icon-button_head" title="' . I18N::translate('Click to choose individual as head of family.') . '"></i>';
433*ad51e0bbSGreg Roach
434*ad51e0bbSGreg Roach		foreach ($family->getSpouses() as $spouse) {
435*ad51e0bbSGreg Roach			$menu  = new Menu(Functions::getCloseRelationshipName($head, $spouse));
436*ad51e0bbSGreg Roach			foreach ($spouse->getChildFamilies() as $grandparents) {
437*ad51e0bbSGreg Roach				foreach ($grandparents->getSpouses() as $grandparent) {
438*ad51e0bbSGreg Roach					$submenu = new Menu(
439*ad51e0bbSGreg Roach						Functions::getCloseRelationshipName($head, $grandparent) . ' - ' . $grandparent->getFullName(),
440*ad51e0bbSGreg Roach						'#',
441*ad51e0bbSGreg Roach						'',
442*ad51e0bbSGreg Roach						array('onclick' => 'return appendCensusRow("' . Filter::escapeJs(CensusAssistantModule::censusTableRow($census, $grandparent, $head)) . '");')
443*ad51e0bbSGreg Roach					);
444*ad51e0bbSGreg Roach					$submenu->addClass('submenuitem', '');
445*ad51e0bbSGreg Roach					$menu->addSubmenu($submenu);
446*ad51e0bbSGreg Roach					$menu->addClass('', 'submenu');
44799f222b3SGreg Roach				}
44899f222b3SGreg Roach			}
44999f222b3SGreg Roach
450*ad51e0bbSGreg Roach			?>
451*ad51e0bbSGreg Roach			<tr>
452*ad51e0bbSGreg Roach				<td class="optionbox">
453*ad51e0bbSGreg Roach					<?php echo $menu->getMenu(); ?>
454*ad51e0bbSGreg Roach				</td>
455*ad51e0bbSGreg Roach				<td class="facts_value nowrap">
456*ad51e0bbSGreg Roach					<a href="#" onclick="return appendCensusRow('<?php echo Filter::escapeJs(CensusAssistantModule::censusTableRow($census, $spouse, $head)); ?>');">
457*ad51e0bbSGreg Roach						<?php echo $spouse->getFullName(); ?>
458*ad51e0bbSGreg Roach					</a>
459*ad51e0bbSGreg Roach				</td>
460*ad51e0bbSGreg Roach				<td align="left" class="facts_value">
461*ad51e0bbSGreg Roach					<a href="edit_interface.php?action=addnewnote_assisted&amp;noteid=newnote&amp;xref=<?php echo $spouse->getXref(); ?>&amp;gedcom=<?php echo $spouse->getTree()->getNameUrl(); ?>&amp;census=<?php echo get_class($census); ?>">
462*ad51e0bbSGreg Roach						<?php echo $headImg2; ?>
463*ad51e0bbSGreg Roach					</a>
464*ad51e0bbSGreg Roach				</td>
465*ad51e0bbSGreg Roach			</tr>
466*ad51e0bbSGreg Roach			<?php
46799f222b3SGreg Roach		}
468*ad51e0bbSGreg Roach
469*ad51e0bbSGreg Roach		foreach ($family->getChildren() as $child) {
470*ad51e0bbSGreg Roach			$menu  = new Menu(Functions::getCloseRelationshipName($head, $child));
471*ad51e0bbSGreg Roach			foreach ($child->getSpouseFamilies() as $spouse_family) {
472*ad51e0bbSGreg Roach				foreach ($spouse_family->getSpouses() as $spouse_family_spouse) {
473*ad51e0bbSGreg Roach					if ($spouse_family_spouse != $child) {
474*ad51e0bbSGreg Roach						$submenu = new Menu(
475*ad51e0bbSGreg Roach							Functions::getCloseRelationshipName($head, $spouse_family_spouse) . ' - ' . $spouse_family_spouse->getFullName(),
476*ad51e0bbSGreg Roach							'#',
477*ad51e0bbSGreg Roach							'',
478*ad51e0bbSGreg Roach							array('onclick' => 'return appendCensusRow("' . Filter::escapeJs(CensusAssistantModule::censusTableRow($census, $spouse_family_spouse, $head)) . '");')
479*ad51e0bbSGreg Roach						);
480*ad51e0bbSGreg Roach						$submenu->addClass('submenuitem', '');
481*ad51e0bbSGreg Roach						$menu->addSubmenu($submenu);
482*ad51e0bbSGreg Roach						$menu->addClass('', 'submenu');
483*ad51e0bbSGreg Roach					}
484*ad51e0bbSGreg Roach				}
485*ad51e0bbSGreg Roach				foreach ($spouse_family->getChildren() as $spouse_family_child) {
486*ad51e0bbSGreg Roach					$submenu = new Menu(
487*ad51e0bbSGreg Roach						Functions::getCloseRelationshipName($head, $spouse_family_child) . ' - ' . $spouse_family_child->getFullName(),
488*ad51e0bbSGreg Roach						'#',
489*ad51e0bbSGreg Roach						'',
490*ad51e0bbSGreg Roach						array('onclick' => 'return appendCensusRow("' . Filter::escapeJs(CensusAssistantModule::censusTableRow($census, $spouse_family_child, $head)) . '");')
491*ad51e0bbSGreg Roach					);
492*ad51e0bbSGreg Roach					$submenu->addClass('submenuitem', '');
493*ad51e0bbSGreg Roach					$menu->addSubmenu($submenu);
494*ad51e0bbSGreg Roach					$menu->addClass('', 'submenu');
49599f222b3SGreg Roach				}
49699f222b3SGreg Roach			}
49799f222b3SGreg Roach
498*ad51e0bbSGreg Roach			?>
499*ad51e0bbSGreg Roach			<tr>
500*ad51e0bbSGreg Roach				<td class="optionbox">
501*ad51e0bbSGreg Roach					<?php echo $menu->getMenu(); ?>
502*ad51e0bbSGreg Roach				</td>
503*ad51e0bbSGreg Roach				<td class="facts_value">
504*ad51e0bbSGreg Roach					<a href="#" onclick="return appendCensusRow('<?php echo Filter::escapeJs(CensusAssistantModule::censusTableRow($census, $child, $head)); ?>');">
505*ad51e0bbSGreg Roach						<?php echo $child->getFullName(); ?>
506*ad51e0bbSGreg Roach					</a>
507*ad51e0bbSGreg Roach				</td>
508*ad51e0bbSGreg Roach				<td class="facts_value">
509*ad51e0bbSGreg Roach					<a href="edit_interface.php?action=addnewnote_assisted&amp;noteid=newnote&amp;xref=<?php echo $child->getXref(); ?>&amp;gedcom=<?php echo $child->getTree()->getNameUrl(); ?>&amp;census=<?php echo get_class($census); ?>">
510*ad51e0bbSGreg Roach						<?php echo $headImg2; ?>
511*ad51e0bbSGreg Roach					</a>
512*ad51e0bbSGreg Roach				</td>
513*ad51e0bbSGreg Roach			</tr>
514*ad51e0bbSGreg Roach			<?php
51599f222b3SGreg Roach		}
516*ad51e0bbSGreg Roach		echo '<tr><td><br></td></tr>';
51799f222b3SGreg Roach	}
5188c2e8227SGreg Roach}
519