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