xref: /webtrees/app/Module/RelativesTabModule.php (revision 89713119637cb08163d7e7c318ae706e55f73c7a)
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 */
1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
1776692c8bSGreg Roach
180e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth;
190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Date;
200e62c4b8SGreg Roachuse Fisharebest\Webtrees\Family;
213d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\Functions;
220e62c4b8SGreg Roachuse Fisharebest\Webtrees\GedcomTag;
230e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Individual;
250e62c4b8SGreg Roachuse Fisharebest\Webtrees\Theme;
268c2e8227SGreg Roach
278c2e8227SGreg Roach/**
288c2e8227SGreg Roach * Class RelativesTabModule
298c2e8227SGreg Roach */
30e2a378d3SGreg Roachclass RelativesTabModule extends AbstractModule implements ModuleTabInterface {
3176692c8bSGreg Roach	/**
3276692c8bSGreg Roach	 * How should this module be labelled on tabs, menus, etc.?
3376692c8bSGreg Roach	 *
3476692c8bSGreg Roach	 * @return string
3576692c8bSGreg Roach	 */
368c2e8227SGreg Roach	public function getTitle() {
378c2e8227SGreg Roach		return /* I18N: Name of a module */ I18N::translate('Families');
388c2e8227SGreg Roach	}
398c2e8227SGreg Roach
4076692c8bSGreg Roach	/**
4176692c8bSGreg Roach	 * A sentence describing what this module does.
4276692c8bSGreg Roach	 *
4376692c8bSGreg Roach	 * @return string
4476692c8bSGreg Roach	 */
458c2e8227SGreg Roach	public function getDescription() {
468c2e8227SGreg Roach		return /* I18N: Description of the “Families” module */ I18N::translate('A tab showing the close relatives of an individual.');
478c2e8227SGreg Roach	}
488c2e8227SGreg Roach
4976692c8bSGreg Roach	/**
5076692c8bSGreg Roach	 * The user can re-arrange the tab order, but until they do, this
5176692c8bSGreg Roach	 * is the order in which tabs are shown.
5276692c8bSGreg Roach	 *
5376692c8bSGreg Roach	 * @return int
5476692c8bSGreg Roach	 */
558c2e8227SGreg Roach	public function defaultTabOrder() {
568c2e8227SGreg Roach		return 20;
578c2e8227SGreg Roach	}
588c2e8227SGreg Roach
598c2e8227SGreg Roach	/**
6076692c8bSGreg Roach	 * Display the age difference between marriages and the births of children.
6176692c8bSGreg Roach	 *
628c2e8227SGreg Roach	 * @param Date $prev
638c2e8227SGreg Roach	 * @param Date $next
64cbc1590aSGreg Roach	 * @param int  $child_number
658c2e8227SGreg Roach	 *
668c2e8227SGreg Roach	 * @return string
678c2e8227SGreg Roach	 */
68ffd703eaSGreg Roach	private static function ageDifference(Date $prev, Date $next, $child_number = 0) {
698c2e8227SGreg Roach		if ($prev->isOK() && $next->isOK()) {
708c2e8227SGreg Roach			$days = $next->maximumJulianDay() - $prev->minimumJulianDay();
718c2e8227SGreg Roach			if ($days < 0) {
728c2e8227SGreg Roach				// Show warning triangle if dates in reverse order
738c2e8227SGreg Roach				$diff = '<i class="icon-warning"></i> ';
748c2e8227SGreg Roach			} elseif ($child_number > 1 && $days > 1 && $days < 240) {
758c2e8227SGreg Roach				// Show warning triangle if children born too close together
768c2e8227SGreg Roach				$diff = '<i class="icon-warning"></i> ';
778c2e8227SGreg Roach			} else {
788c2e8227SGreg Roach				$diff = '';
798c2e8227SGreg Roach			}
808c2e8227SGreg Roach
818c2e8227SGreg Roach			$months = round($days * 12 / 365.25); // Approximate - we do not know the calendar
828c2e8227SGreg Roach			if (abs($months) == 12 || abs($months) >= 24) {
83def7396fSGreg Roach				$diff .= I18N::plural('%s year', '%s years', round($months / 12), I18N::number(round($months / 12)));
848c2e8227SGreg Roach			} elseif ($months != 0) {
85def7396fSGreg Roach				$diff .= I18N::plural('%s month', '%s months', $months, I18N::number($months));
868c2e8227SGreg Roach			}
878c2e8227SGreg Roach
888c2e8227SGreg Roach			return '<div class="elderdate age">' . $diff . '</div>';
898c2e8227SGreg Roach		} else {
908c2e8227SGreg Roach			return '';
918c2e8227SGreg Roach		}
928c2e8227SGreg Roach	}
938c2e8227SGreg Roach
948c2e8227SGreg Roach	/**
9576692c8bSGreg Roach	 * Print a family group.
9676692c8bSGreg Roach	 *
978c2e8227SGreg Roach	 * @param Family $family
988c2e8227SGreg Roach	 * @param string $type
998c2e8227SGreg Roach	 * @param string $label
1008c2e8227SGreg Roach	 */
101ffd703eaSGreg Roach	private function printFamily(Family $family, $type, $label) {
1028c2e8227SGreg Roach		global $controller;
1038c2e8227SGreg Roach
1044b9ff166SGreg Roach		if ($family->getTree()->getPreference('SHOW_PRIVATE_RELATIONSHIPS')) {
1054b9ff166SGreg Roach			$access_level = Auth::PRIV_HIDE;
1068c2e8227SGreg Roach		} else {
1074b9ff166SGreg Roach			$access_level = Auth::accessLevel($family->getTree());
1088c2e8227SGreg Roach		}
1098c2e8227SGreg Roach
1108c2e8227SGreg Roach		?>
1118c2e8227SGreg Roach		<table>
1128c2e8227SGreg Roach			<tr>
1138c2e8227SGreg Roach				<td>
1148c2e8227SGreg Roach					<i class="icon-cfamily"></i>
1158c2e8227SGreg Roach				</td>
1168c2e8227SGreg Roach				<td>
11715d603e7SGreg Roach					<span class="subheaders"> <?= $label ?></span>
11815d603e7SGreg Roach					<a href="<?= $family->getHtmlUrl() ?>"> - <?= I18N::translate('View this family') ?></a>
1198c2e8227SGreg Roach				</td>
1208c2e8227SGreg Roach			</tr>
1218c2e8227SGreg Roach		</table>
122e0486a06SGreg Roach
123e0486a06SGreg Roach		<table class="table table-sm wt-facts-table">
124e0486a06SGreg Roach		<caption></caption>
125e0486a06SGreg Roach		<tbody>
1268c2e8227SGreg Roach		<?php
1278c2e8227SGreg Roach
1288c2e8227SGreg Roach		///// HUSB /////
1298c2e8227SGreg Roach		$found = false;
1308c2e8227SGreg Roach		foreach ($family->getFacts('HUSB', false, $access_level) as $fact) {
1318c2e8227SGreg Roach			$found |= !$fact->isPendingDeletion();
1328c2e8227SGreg Roach			$person = $fact->getTarget();
1338c2e8227SGreg Roach			if ($person instanceof Individual) {
134e0486a06SGreg Roach				$row_class = 'wt-gender-' . $person->getSex();
1358c2e8227SGreg Roach				if ($fact->isPendingAddition()) {
136e0486a06SGreg Roach					$row_class .= ' new';
1378c2e8227SGreg Roach				} elseif ($fact->isPendingDeletion()) {
138e0486a06SGreg Roach					$row_class .= ' old';
1398c2e8227SGreg Roach				}
140*89713119SGreg Roach				$icon = $controller->record === $person ? '<i class="icon-selected"></i>' : '';
1418c2e8227SGreg Roach				?>
142e0486a06SGreg Roach					<tr class="<?= $row_class ?>">
143e0486a06SGreg Roach						<th scope="row">
144*89713119SGreg Roach							<?= $icon ?>
14515d603e7SGreg Roach							<?= Functions::getCloseRelationshipName($controller->record, $person) ?>
146e0486a06SGreg Roach						</th>
147e0486a06SGreg Roach						<td class="border-0 p-0">
14815d603e7SGreg Roach							<?= Theme::theme()->individualBoxLarge($person) ?>
1498c2e8227SGreg Roach						</td>
1508c2e8227SGreg Roach					</tr>
1518c2e8227SGreg Roach				<?php
1528c2e8227SGreg Roach			}
1538c2e8227SGreg Roach		}
1548c2e8227SGreg Roach		if (!$found && $family->canEdit()) {
1558c2e8227SGreg Roach			?>
1568c2e8227SGreg Roach			<tr>
157e0486a06SGreg Roach				<th></th>
158e0486a06SGreg Roach				<td scope="row">
15915d603e7SGreg Roach					<a href="edit_interface.php?action=add_spouse_to_family&amp;ged=<?= $family->getTree()->getNameHtml() ?>&amp;xref=<?= $family->getXref() ?>&amp;famtag=HUSB">
16015d603e7SGreg Roach						<?= I18N::translate('Add a husband to this family') ?>
16115d603e7SGreg Roach					</a>
16215d603e7SGreg Roach					</td>
1638c2e8227SGreg Roach			</tr>
1648c2e8227SGreg Roach			<?php
1658c2e8227SGreg Roach		}
1668c2e8227SGreg Roach
1678c2e8227SGreg Roach		///// WIFE /////
1688c2e8227SGreg Roach		$found = false;
1698c2e8227SGreg Roach		foreach ($family->getFacts('WIFE', false, $access_level) as $fact) {
1708c2e8227SGreg Roach			$person = $fact->getTarget();
1718c2e8227SGreg Roach			if ($person instanceof Individual) {
1728c2e8227SGreg Roach				$found |= !$fact->isPendingDeletion();
173e0486a06SGreg Roach				$row_class = 'wt-gender-' . $person->getSex();
1748c2e8227SGreg Roach				if ($fact->isPendingAddition()) {
175e0486a06SGreg Roach					$row_class .= ' new';
1768c2e8227SGreg Roach				} elseif ($fact->isPendingDeletion()) {
177e0486a06SGreg Roach					$row_class .= ' old';
1788c2e8227SGreg Roach				}
179*89713119SGreg Roach				$icon = $controller->record === $person ? '<i class="icon-selected"></i>' : '';
1808c2e8227SGreg Roach        ?>
181e0486a06SGreg Roach				<tr class="<?= $row_class ?>">
182e0486a06SGreg Roach					<th scope="row">
183*89713119SGreg Roach					<?= $icon ?>
18415d603e7SGreg Roach					<?= Functions::getCloseRelationshipName($controller->record, $person) ?>
185e0486a06SGreg Roach					</th>
186e0486a06SGreg Roach					<td class="border-0 p-0">
18715d603e7SGreg Roach						<?= Theme::theme()->individualBoxLarge($person) ?>
1888c2e8227SGreg Roach					</td>
1898c2e8227SGreg Roach				</tr>
1908c2e8227SGreg Roach				<?php
1918c2e8227SGreg Roach			}
1928c2e8227SGreg Roach		}
1938c2e8227SGreg Roach		if (!$found && $family->canEdit()) {
1948c2e8227SGreg Roach			?>
1958c2e8227SGreg Roach			<tr>
196e0486a06SGreg Roach				<th scope="row"></th>
197e0486a06SGreg Roach				<td>
19815d603e7SGreg Roach					<a href="edit_interface.php?action=add_spouse_to_family&amp;ged=<?= $family->getTree()->getNameHtml() ?>&amp;xref=<?= $family->getXref() ?>&amp;famtag=WIFE">
19915d603e7SGreg Roach						<?= I18N::translate('Add a wife to this family') ?>
20015d603e7SGreg Roach					</a>
20115d603e7SGreg Roach				</td>
2028c2e8227SGreg Roach			</tr>
2038c2e8227SGreg Roach			<?php
2048c2e8227SGreg Roach		}
2058c2e8227SGreg Roach
2068c2e8227SGreg Roach		///// MARR /////
2078c2e8227SGreg Roach		$found = false;
2088c2e8227SGreg Roach		$prev  = new Date('');
209a35df85eSGreg Roach		foreach ($family->getFacts(WT_EVENTS_MARR . '|' . WT_EVENTS_DIV, true) as $fact) {
2108c2e8227SGreg Roach			$found |= !$fact->isPendingDeletion();
2118c2e8227SGreg Roach			if ($fact->isPendingAddition()) {
212e0486a06SGreg Roach				$row_class = 'new';
2138c2e8227SGreg Roach			} elseif ($fact->isPendingDeletion()) {
214e0486a06SGreg Roach				$row_class = 'old';
2158c2e8227SGreg Roach			} else {
216e0486a06SGreg Roach				$row_class = '';
2178c2e8227SGreg Roach			}
2188c2e8227SGreg Roach			?>
219e0486a06SGreg Roach			<tr class="<?= $row_class ?>">
220e0486a06SGreg Roach				<th scope="row">
221e0486a06SGreg Roach				</th>
222e0486a06SGreg Roach				<td>
22315d603e7SGreg Roach					<?= GedcomTag::getLabelValue($fact->getTag(), $fact->getDate()->display() . ' — ' . $fact->getPlace()->getFullName()) ?>
2248c2e8227SGreg Roach				</td>
2258c2e8227SGreg Roach			</tr>
2268c2e8227SGreg Roach			<?php
2278c2e8227SGreg Roach			if (!$prev->isOK() && $fact->getDate()->isOK()) {
2288c2e8227SGreg Roach				$prev = $fact->getDate();
2298c2e8227SGreg Roach			}
2308c2e8227SGreg Roach		}
2318c2e8227SGreg Roach		if (!$found && $family->canShow() && $family->canEdit()) {
2328c2e8227SGreg Roach			// Add a new marriage
2338c2e8227SGreg Roach			?>
2348c2e8227SGreg Roach			<tr>
235e0486a06SGreg Roach				<th scope="row">
236e0486a06SGreg Roach				</th>
237e0486a06SGreg Roach				<td>
23815d603e7SGreg Roach					<a href="edit_interface.php?action=add&amp;ged=<?= $family->getTree()->getNameHtml() ?>&amp;xref=<?= $family->getXref() ?>&amp;fact=MARR">
23915d603e7SGreg Roach						<?= I18N::translate('Add marriage details') ?>
2408c2e8227SGreg Roach					</a>
2418c2e8227SGreg Roach				</td>
2428c2e8227SGreg Roach			</tr>
2438c2e8227SGreg Roach			<?php
2448c2e8227SGreg Roach		}
2458c2e8227SGreg Roach
2468c2e8227SGreg Roach		///// CHIL /////
2478c2e8227SGreg Roach		$child_number = 0;
2488c2e8227SGreg Roach		foreach ($family->getFacts('CHIL', false, $access_level) as $fact) {
2498c2e8227SGreg Roach			$person = $fact->getTarget();
2508c2e8227SGreg Roach			if ($person instanceof Individual) {
251e0486a06SGreg Roach				$row_class = 'wt-gender-' . $person->getSex();
2528c2e8227SGreg Roach				if ($fact->isPendingAddition()) {
2538c2e8227SGreg Roach					$child_number++;
254e0486a06SGreg Roach					$row_class .= ' new';
2558c2e8227SGreg Roach				} elseif ($fact->isPendingDeletion()) {
256e0486a06SGreg Roach					$row_class .= ' old';
2578c2e8227SGreg Roach				} else {
2588c2e8227SGreg Roach					$child_number++;
2598c2e8227SGreg Roach				}
2608c2e8227SGreg Roach				$next = new Date('');
261fd0dfcc2SGreg Roach				foreach ($person->getFacts(WT_EVENTS_BIRT, true) as $bfact) {
2628c2e8227SGreg Roach					if ($bfact->getDate()->isOK()) {
2638c2e8227SGreg Roach						$next = $bfact->getDate();
2648c2e8227SGreg Roach						break;
2658c2e8227SGreg Roach					}
2668c2e8227SGreg Roach				}
267*89713119SGreg Roach				$icon = $controller->record === $person ? '<i class="icon-selected"></i>' : '';
2688c2e8227SGreg Roach				?>
269e0486a06SGreg Roach				<tr class="<?= $row_class ?>">
270e0486a06SGreg Roach					<th scope="row">
271*89713119SGreg Roach						<?= $icon ?>
27215d603e7SGreg Roach						<?= self::ageDifference($prev, $next, $child_number) ?>
27315d603e7SGreg Roach						<?= Functions::getCloseRelationshipName($controller->record, $person) ?>
274e0486a06SGreg Roach					</th>
275e0486a06SGreg Roach					<td class="border-0 p-0">
27615d603e7SGreg Roach						<?= Theme::theme()->individualBoxLarge($person) ?>
2778c2e8227SGreg Roach					</td>
2788c2e8227SGreg Roach				</tr>
2798c2e8227SGreg Roach				<?php
2808c2e8227SGreg Roach				$prev = $next;
2818c2e8227SGreg Roach			}
2828c2e8227SGreg Roach		}
2838c2e8227SGreg Roach		// Re-order children / add a new child
2848c2e8227SGreg Roach		if ($family->canEdit()) {
2858c2e8227SGreg Roach			if ($type == 'FAMS') {
28629bb8efbSGreg Roach				$add_child_text = I18N::translate('Add a son or daughter');
2878c2e8227SGreg Roach			} else {
28829bb8efbSGreg Roach				$add_child_text = I18N::translate('Add a brother or sister');
2898c2e8227SGreg Roach			}
2908c2e8227SGreg Roach			?>
29115d603e7SGreg Roach			<tr>
292e0486a06SGreg Roach				<th scope="row">
29315d603e7SGreg Roach					<?php if (count($family->getChildren()) > 1): ?>
29468b32ba8SGreg Roach					<a href="edit_interface.php?action=reorder-children&amp;ged=<?= $family->getTree()->getNameHtml() ?>&amp;xref=<?= $family->getXref() ?>">
29515d603e7SGreg Roach						<i class="icon-media-shuffle"></i> <?= I18N::translate('Re-order children') ?>
29615d603e7SGreg Roach					</a>
29715d603e7SGreg Roach					<?php endif; ?>
298e0486a06SGreg Roach				</th>
299e0486a06SGreg Roach				<td>
30015d603e7SGreg Roach					<a href="edit_interface.php?action=add_child_to_family&amp;ged=<?= $family->getTree()->getNameHtml() ?>&amp;xref=<?= $family->getXref() ?>&amp;gender=U">
30115d603e7SGreg Roach						<?= $add_child_text ?>
30215d603e7SGreg Roach					</a>
3038c2e8227SGreg Roach					<span style='white-space:nowrap;'>
30415d603e7SGreg Roach						<a href="edit_interface.php?action=add_child_to_family&amp;ged=<?= $family->getTree()->getNameHtml() ?>&amp;xref=<?= $family->getXref() ?>&amp;gender=M" class="icon-sex_m_15x15"></a>
30515d603e7SGreg Roach						<a href="edit_interface.php?action=add_child_to_family&amp;ged=<?= $family->getTree()->getNameHtml() ?>&amp;xref=<?= $family->getXref() ?>&amp;gender=F" class="icon-sex_f_15x15"></a>
3068c2e8227SGreg Roach					</span>
3078c2e8227SGreg Roach				</td>
3088c2e8227SGreg Roach			</tr>
3098c2e8227SGreg Roach			<?php
3108c2e8227SGreg Roach		}
3118c2e8227SGreg Roach
312e0486a06SGreg Roach		echo '</tbody>';
3138c2e8227SGreg Roach		echo '</table>';
3148c2e8227SGreg Roach	}
3158c2e8227SGreg Roach
3168c2e8227SGreg Roach	/** {@inheritdoc} */
3178c2e8227SGreg Roach	public function getTabContent() {
31815d603e7SGreg Roach		global $controller;
3198c2e8227SGreg Roach
3208c2e8227SGreg Roach		ob_start();
3218c2e8227SGreg Roach		?>
322024989f8SCarmen Pijpers		<table class="table table-sm wt-facts-table" role="presentation">
323e0486a06SGreg Roach			<tbody>
32415d603e7SGreg Roach				<tr>
325e0486a06SGreg Roach					<td>
326877e7017SGreg Roach						<label>
32723c362a9SGreg Roach							<input id="show-date-differences" type="checkbox" checked>
32815d603e7SGreg Roach							<?= I18N::translate('Date differences') ?>
32907660c67SGreg Roach						</label>
33007660c67SGreg Roach					</td>
33107660c67SGreg Roach				</tr>
332e0486a06SGreg Roach			</tbody>
33307660c67SGreg Roach		</table>
3348c2e8227SGreg Roach		<?php
3358c2e8227SGreg Roach		$families = $controller->record->getChildFamilies();
3368c2e8227SGreg Roach		if (!$families && $controller->record->canEdit()) {
3378c2e8227SGreg Roach			?>
338e0486a06SGreg Roach			<table class="table table-sm wt-facts-table">
339e0486a06SGreg Roach				<tbody>
3408c2e8227SGreg Roach					<tr>
341e0486a06SGreg Roach						<td>
34215d603e7SGreg Roach							<a href="edit_interface.php?action=add_parent_to_individual&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>&amp;gender=M">
34315d603e7SGreg Roach								<?= I18N::translate('Add a father') ?>
34415d603e7SGreg Roach							</a>
34515d603e7SGreg Roach						</td>
3468c2e8227SGreg Roach					</tr>
3478c2e8227SGreg Roach					<tr>
348e0486a06SGreg Roach						<td>
34915d603e7SGreg Roach							<a href="edit_interface.php?action=add_parent_to_individual&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>&amp;gender=F">
35015d603e7SGreg Roach								<?= I18N::translate('Add a mother') ?>
35115d603e7SGreg Roach							</a>
35215d603e7SGreg Roach						</td>
3538c2e8227SGreg Roach					</tr>
354e0486a06SGreg Roach				</tbody>
3558c2e8227SGreg Roach			</table>
3568c2e8227SGreg Roach			<?php
3578c2e8227SGreg Roach		}
3588c2e8227SGreg Roach
3598c2e8227SGreg Roach		// parents
3608c2e8227SGreg Roach		foreach ($families as $family) {
3618c2e8227SGreg Roach			$this->printFamily($family, 'FAMC', $controller->record->getChildFamilyLabel($family));
3628c2e8227SGreg Roach		}
3638c2e8227SGreg Roach
3648c2e8227SGreg Roach		// step-parents
3658c2e8227SGreg Roach		foreach ($controller->record->getChildStepFamilies() as $family) {
3668c2e8227SGreg Roach			$this->printFamily($family, 'FAMC', $controller->record->getStepFamilyLabel($family));
3678c2e8227SGreg Roach		}
3688c2e8227SGreg Roach
3698c2e8227SGreg Roach		// spouses
3708c2e8227SGreg Roach		$families = $controller->record->getSpouseFamilies();
3718c2e8227SGreg Roach		foreach ($families as $family) {
372268bcb45SGreg Roach			$this->printFamily($family, 'FAMS', $controller->getSpouseFamilyLabel($family, $controller->record));
3738c2e8227SGreg Roach		}
3748c2e8227SGreg Roach
3758c2e8227SGreg Roach		// step-children
3768c2e8227SGreg Roach		foreach ($controller->record->getSpouseStepFamilies() as $family) {
3778c2e8227SGreg Roach			$this->printFamily($family, 'FAMS', $family->getFullName());
3788c2e8227SGreg Roach		}
3798c2e8227SGreg Roach
3808c2e8227SGreg Roach		if ($controller->record->canEdit()) {
3818c2e8227SGreg Roach		?>
382e0486a06SGreg Roach		<br>
383e0486a06SGreg Roach		<table class="table table-sm wt-facts-table">
384e0486a06SGreg Roach			<tbody>
385e0486a06SGreg Roach				<?php if (count($families) > 1) { ?>
3868c2e8227SGreg Roach				<tr>
387e0486a06SGreg Roach					<td>
38868b32ba8SGreg Roach						<a href="edit_interface.php?action=reorder-spouses&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>">
38915d603e7SGreg Roach						<?= I18N::translate('Re-order families') ?>
39015d603e7SGreg Roach						</a>
3918c2e8227SGreg Roach					</td>
3928c2e8227SGreg Roach				</tr>
3938c2e8227SGreg Roach			<?php } ?>
3948c2e8227SGreg Roach				<tr>
395e0486a06SGreg Roach					<td>
39615d603e7SGreg Roach					<a href="edit_interface.php?action=addfamlink&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>"><?= I18N::translate('Link this individual to an existing family as a child') ?></a>
3978c2e8227SGreg Roach					</td>
3988c2e8227SGreg Roach				</tr>
39915d603e7SGreg Roach				<?php if ($controller->record->getSex() !== 'F') { ?>
4008c2e8227SGreg Roach				<tr>
401e0486a06SGreg Roach					<td>
40215d603e7SGreg Roach					<a href="edit_interface.php?action=add_spouse_to_individual&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>&amp;sex=F"><?= I18N::translate('Add a wife') ?></a>
4038c2e8227SGreg Roach					</td>
4048c2e8227SGreg Roach				</tr>
4058c2e8227SGreg Roach				<tr>
406e0486a06SGreg Roach					<td>
40715d603e7SGreg Roach					<a href="edit_interface.php?action=linkspouse&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>&amp;famtag=WIFE"><?= I18N::translate('Add a wife using an existing individual') ?></a>
4088c2e8227SGreg Roach					</td>
4098c2e8227SGreg Roach				</tr>
410e0486a06SGreg Roach				<?php } ?>
411e0486a06SGreg Roach				<?php if ($controller->record->getSex() !== 'M') { ?>
4128c2e8227SGreg Roach				<tr>
413e0486a06SGreg Roach					<td>
41415d603e7SGreg Roach					<a href="edit_interface.php?action=add_spouse_to_individual&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>&amp;sex=M"><?= I18N::translate('Add a husband') ?></a>
4158c2e8227SGreg Roach					</td>
4168c2e8227SGreg Roach				</tr>
4178c2e8227SGreg Roach				<tr>
418e0486a06SGreg Roach					<td>
41915d603e7SGreg Roach					<a href="edit_interface.php?action=linkspouse&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>&amp;famtag=HUSB"><?= I18N::translate('Add a husband using an existing individual') ?></a>
4208c2e8227SGreg Roach					</td>
4218c2e8227SGreg Roach				</tr>
4228c2e8227SGreg Roach				<?php } ?>
4238c2e8227SGreg Roach				<tr>
424e0486a06SGreg Roach					<td>
42515d603e7SGreg Roach						<a href="edit_interface.php?action=add_child_to_individual&amp;ged=<?= $controller->record->getTree()->getNameHtml() ?>&amp;xref=<?= $controller->record->getXref() ?>&amp;gender=U">
42615d603e7SGreg Roach							<?= I18N::translate('Add a child to create a one-parent family') ?>
42715d603e7SGreg Roach						</a>
4288c2e8227SGreg Roach					</td>
4298c2e8227SGreg Roach				</tr>
430e0486a06SGreg Roach			</tbody>
4318c2e8227SGreg Roach		</table>
4328c2e8227SGreg Roach		<?php } ?>
4338c2e8227SGreg Roach		<br>
434f591304fSGreg Roach		<script>
43515d603e7SGreg Roach			//persistent_toggle("show-date-differences", ".elderdate");
436f591304fSGreg Roach		</script>
4378c2e8227SGreg Roach		<?php
4388c2e8227SGreg Roach
4398c2e8227SGreg Roach		return '<div id="' . $this->getName() . '_content">' . ob_get_clean() . '</div>';
4408c2e8227SGreg Roach	}
4418c2e8227SGreg Roach
4428c2e8227SGreg Roach	/** {@inheritdoc} */
4438c2e8227SGreg Roach	public function hasTabContent() {
4448c2e8227SGreg Roach		return true;
4458c2e8227SGreg Roach	}
4468c2e8227SGreg Roach	/** {@inheritdoc} */
4478c2e8227SGreg Roach	public function isGrayedOut() {
4488c2e8227SGreg Roach		return false;
4498c2e8227SGreg Roach	}
4508c2e8227SGreg Roach	/** {@inheritdoc} */
4518c2e8227SGreg Roach	public function canLoadAjax() {
45215d603e7SGreg Roach		return false;
4538c2e8227SGreg Roach	}
4548c2e8227SGreg Roach
4558c2e8227SGreg Roach	/** {@inheritdoc} */
4568c2e8227SGreg Roach	public function getPreLoadContent() {
4578c2e8227SGreg Roach		return '';
4588c2e8227SGreg Roach	}
4598c2e8227SGreg Roach}
460