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