1<?php 2 3declare(strict_types=1); 4 5use Fisharebest\Webtrees\I18N; 6use Fisharebest\Webtrees\Note; 7use Fisharebest\Webtrees\Tree; 8use Illuminate\Database\Capsule\Manager as DB; 9use Illuminate\Database\Query\Expression; 10use Illuminate\Database\Query\JoinClause; 11use Illuminate\Support\Collection; 12 13/** 14 * @var Collection<int,Note> $notes 15 * @var Tree $tree 16 */ 17 18?> 19 20<?php 21// Count the number of linked records. These numbers include private records. 22// It is not good to bypass privacy, but many servers do not have the resources 23// to process privacy for every record in the tree 24$count_individuals = DB::table('individuals') 25 ->join('link', static function (JoinClause $join): void { 26 $join->on('l_from', '=', 'i_id'); 27 $join->on('l_file', '=', 'i_file'); 28 }) 29 ->where('l_type', '=', 'NOTE') 30 ->where('l_file', '=', $tree->id()) 31 ->groupBy(['l_to']) 32 ->select(['l_to', new Expression('COUNT(*) AS total')]) 33 ->pluck('total', 'l_to') 34 ->map(static fn (string $n) => (int) $n) 35 ->all(); 36 37$count_families = DB::table('families') 38 ->join('link', static function (JoinClause $join): void { 39 $join->on('l_from', '=', 'f_id'); 40 $join->on('l_file', '=', 'f_file'); 41 }) 42 ->where('l_type', '=', 'NOTE') 43 ->where('l_file', '=', $tree->id()) 44 ->groupBy(['l_to']) 45 ->select(['l_to', new Expression('COUNT(*) AS total')]) 46 ->pluck('total', 'l_to') 47 ->map(static fn (string $n) => (int) $n) 48 ->all(); 49 50$count_media = DB::table('media') 51 ->join('link', static function (JoinClause $join): void { 52 $join->on('l_from', '=', 'm_id'); 53 $join->on('l_file', '=', 'm_file'); 54 }) 55 ->where('l_type', '=', 'NOTE') 56 ->where('l_file', '=', $tree->id()) 57 ->groupBy(['l_to']) 58 ->select(['l_to', new Expression('COUNT(*) AS total')]) 59 ->pluck('total', 'l_to') 60 ->map(static fn (string $n) => (int) $n) 61 ->all(); 62 63$count_sources = DB::table('sources') 64 ->join('link', static function (JoinClause $join): void { 65 $join->on('l_from', '=', 's_id'); 66 $join->on('l_file', '=', 's_file'); 67 }) 68 ->where('l_type', '=', 'NOTE') 69 ->where('l_file', '=', $tree->id()) 70 ->groupBy(['l_to']) 71 ->select(['l_to', new Expression('COUNT(*) AS total')]) 72 ->pluck('total', 'l_to') 73 ->map(static fn (string $n) => (int) $n) 74 ->all(); 75?> 76 77<table 78 class="table table-bordered table-sm wt-table-note datatables d-none" 79 <?= view('lists/datatables-attributes') ?> 80 data-columns="<?= e(json_encode([ 81 ['type' => 'html'], 82 ['visible' => array_sum($count_individuals) > 0], 83 ['visible' => array_sum($count_families) > 0], 84 ['visible' => array_sum($count_media) > 0], 85 ['visible' => array_sum($count_sources) > 0], 86 ['visible' => (bool) $tree->getPreference('SHOW_LAST_CHANGE'), 'searchable' => false], 87 ], JSON_THROW_ON_ERROR)) ?>" 88> 89 <caption class="visually-hidden"> 90 <?= $caption ?? I18N::translate('Sources') ?> 91 </caption> 92 93 <thead> 94 <tr> 95 <th><?= I18N::translate('Title') ?></th> 96 <th><?= I18N::translate('Individuals') ?></th> 97 <th><?= I18N::translate('Families') ?></th> 98 <th><?= I18N::translate('Media objects') ?></th> 99 <th><?= I18N::translate('Sources') ?></th> 100 <th><?= I18N::translate('Last change') ?></th> 101 </tr> 102 </thead> 103 104 <tbody> 105 <?php foreach ($notes as $note) : ?> 106 <tr class="<?= $note->isPendingAddition() ? 'wt-new' : '' ?> <?= $note->isPendingDeletion() ? 'wt-old' : '' ?>"> 107 <!-- Title --> 108 <td data-sort="<?= e($note->sortName()) ?>"> 109 <a href="<?= e($note->url()) ?>"> 110 <?= $note->fullName() ?> 111 </a> 112 </td> 113 114 <!-- Count of linked individuals --> 115 <td class="text-center" data-sort="<?= $count_individuals[$note->xref()] ?? 0 ?>"> 116 <?= I18N::number($count_individuals[$note->xref()] ?? 0) ?> 117 </td> 118 119 <!-- Count of linked families --> 120 <td class="text-center" data-sort="<?= $count_families[$note->xref()] ?? 0 ?>"> 121 <?= I18N::number($count_families[$note->xref()] ?? 0) ?> 122 </td> 123 124 <!-- Count of linked media objects --> 125 <td class="text-center" data-sort="<?= $count_media[$note->xref()] ?? 0 ?>"> 126 <?= I18N::number($count_media[$note->xref()] ?? 0) ?> 127 </td> 128 129 <!-- Count of sources --> 130 <td class="text-center" data-sort="<?= $count_sources[$note->xref()] ?? 0 ?>"> 131 <?= I18N::number($count_sources[$note->xref()] ?? 0) ?> 132 </td> 133 134 <!-- Last change --> 135 <td data-sort="<?= $note->lastChangeTimestamp()->timestamp() ?>"> 136 <?= view('components/datetime', ['timestamp' => $note->lastChangeTimestamp()]) ?> 137 </td> 138 </tr> 139 <?php endforeach ?> 140 </tbody> 141</table> 142