1<?php 2 3use Fisharebest\Webtrees\I18N; 4use Fisharebest\Webtrees\Location; 5use Fisharebest\Webtrees\Tree; 6use Illuminate\Database\Capsule\Manager as DB; 7use Illuminate\Database\Query\Expression; 8use Illuminate\Database\Query\JoinClause; 9use Illuminate\Support\Collection; 10 11/** 12 * @var Collection<Location> $locations 13 * @var Tree $tree 14 */ 15 16?> 17 18<?php 19// Count the number of linked records. These numbers include private records. 20// It is not good to bypass privacy, but many servers do not have the resources 21// to process privacy for every record in the tree 22$count_individuals = DB::table('individuals') 23 ->join('link', static function (JoinClause $join): void { 24 $join->on('l_from', '=', 'i_id'); 25 $join->on('l_file', '=', 'i_file'); 26 }) 27 ->where('l_type', '=', '_LOC') 28 ->where('l_file', '=', $tree->id()) 29 ->groupBy(['l_to']) 30 ->select(['l_to', new Expression('COUNT(*) AS total')]) 31 ->pluck('total', 'l_to') 32 ->all(); 33 34$count_families = DB::table('families') 35 ->join('link', static function (JoinClause $join): void { 36 $join->on('l_from', '=', 'f_id'); 37 $join->on('l_file', '=', 'f_file'); 38 }) 39 ->where('l_type', '=', '_LOC') 40 ->where('l_file', '=', $tree->id()) 41 ->groupBy(['l_to']) 42 ->select(['l_to', new Expression('COUNT(*) AS total')]) 43 ->pluck('total', 'l_to') 44 ->all(); 45?> 46 47<table 48 class="table table-bordered table-sm wt-table-location datatables d-none" 49 <?= view('lists/datatables-attributes') ?> 50 data-columns="<?= e(json_encode([ 51 ['type' => 'html'], 52 ['visible' => array_sum($count_individuals) > 0], 53 ['visible' => array_sum($count_families) > 0], 54 ['visible' => (bool) $tree->getPreference('SHOW_LAST_CHANGE'), 'searchable' => false], 55 ], JSON_THROW_ON_ERROR)) ?>" 56> 57 <caption class="visually-hidden"> 58 <?= $caption ?? I18N::translate('Locations') ?> 59 </caption> 60 61 <thead> 62 <tr> 63 <th><?= I18N::translate('Location') ?></th> 64 <th><?= I18N::translate('Individuals') ?></th> 65 <th><?= I18N::translate('Families') ?></th> 66 <th><?= I18N::translate('Last change') ?></th> 67 </tr> 68 </thead> 69 70 <tbody> 71 <?php foreach ($locations as $location) : ?> 72 <tr class="<?= $location->isPendingAddition() ? 'wt-new' : '' ?> <?= $location->isPendingDeletion() ? 'wt-old' : '' ?>"> 73 <!-- Location name --> 74 <td data-sort="<?= e($location->sortName()) ?>"> 75 <a href="<?= e($location->url()) ?>"> 76 <?= $location->fullName() ?> 77 </a> 78 </td> 79 80 <!-- Count of linked individuals --> 81 <td class="text-center" data-sort="<?= $count_individuals[$location->xref()] ?? 0 ?>"> 82 <?= I18N::number($count_individuals[$location->xref()] ?? 0) ?> 83 </td> 84 85 <!-- Count of linked families --> 86 <td class="text-center" data-sort="<?= $count_families[$location->xref()] ?? 0 ?>"> 87 <?= I18N::number($count_families[$location->xref()] ?? 0) ?> 88 </td> 89 90 <!-- Last change --> 91 <td data-sort="<?= $location->lastChangeTimestamp()->unix() ?>"> 92 <?= view('components/datetime', ['timestamp' => $location->lastChangeTimestamp()]) ?> 93 </td> 94 </tr> 95 <?php endforeach ?> 96 </tbody> 97</table> 98