xref: /webtrees/resources/views/chart-box.phtml (revision 1ff45046fabc22237b5d0d8e489c96f031fc598d)
1<?php
2
3declare(strict_types=1);
4
5use Fisharebest\Webtrees\Auth;
6use Fisharebest\Webtrees\Fact;
7use Fisharebest\Webtrees\Gedcom;
8use Fisharebest\Webtrees\I18N;
9use Fisharebest\Webtrees\Individual;
10use Fisharebest\Webtrees\Menu;
11use Fisharebest\Webtrees\Module\ModuleChartInterface;
12use Fisharebest\Webtrees\Registry;
13use Fisharebest\Webtrees\Services\ModuleService;
14use Illuminate\Support\Collection;
15
16/**
17 * @var Individual|null   $individual
18 * @var ModuleService     $module_service
19 * @var Collection|Menu[] $menus
20 */
21
22if ($individual === null) {
23    echo '<div class="wt-chart-box"></div>';
24
25    return;
26}
27
28$module_service = Registry::container()->get(ModuleService::class);
29
30$menus = $module_service->findByComponent(ModuleChartInterface::class, $individual->tree(), Auth::user())->map(static function (ModuleChartInterface $module) use ($individual): Menu|null {
31    return $module->chartBoxMenu($individual);
32})->filter();
33
34foreach ($individual->spouseFamilies() as $family) {
35    $menus->push(new Menu('<strong>' . I18N::translate('Family with spouse') . '</strong>', $family->url()));
36    $spouse  = $family->spouse($individual);
37    if ($spouse && $spouse->canShow()) {
38        $menus->push(new Menu($spouse->fullName(), $spouse->url()));
39    }
40    foreach ($family->children() as $child) {
41        if ($child->canShow()) {
42            $menus->push(new Menu($child->fullName(), $child->url()));
43        }
44    }
45}
46
47// Do not show these facts in the expanded chart boxes.
48$exclude = [
49    'FAM:CHAN',
50    'FAM:CHIL',
51    'FAM:HUSB',
52    'FAM:NOTE',
53    'FAM:OBJE',
54    'FAM:RESN',
55    'FAM:SOUR',
56    'FAM:WIFE',
57    'INDI:ADDR',
58    'INDI:ALIA',
59    'INDI:ASSO',
60    'INDI:CHAN',
61    'INDI:EMAIL',
62    'INDI:FAMC',
63    'INDI:FAMS',
64    'INDI:NAME',
65    'INDI:NOTE',
66    'INDI:OBJE',
67    'INDI:PHON',
68    'INDI:RESI',
69    'INDI:RESN',
70    'INDI:SEX',
71    'INDI:SOUR',
72    'INDI:SSN',
73    'INDI:SUBM',
74    'INDI:TITL',
75    'INDI:URL',
76    'INDI:WWW',
77    'INDI:_EMAIL',
78    'INDI:_TODO',
79    'INDI:_UID',
80    'INDI:_WT_OBJE_SORT'
81];
82
83/** @var Collection|Fact[] $all_facts */
84$all_facts = $individual->facts();
85foreach ($individual->spouseFamilies() as $family) {
86    foreach ($family->facts() as $fact) {
87        $all_facts->push($fact);
88    }
89}
90
91$all_facts = $all_facts->filter(static function (Fact $fact) use ($exclude): bool {
92    return !in_array($fact->tag(), $exclude, true);
93});
94
95$all_facts = Fact::sortFacts($all_facts);
96
97$id = Registry::idFactory()->id();
98?>
99
100<div class="wt-chart-box wt-chart-box-<?= strtolower($individual->sex()) ?> <?= $individual->isPendingAddition() ? 'wt-new' : '' ?> <?= $individual->isPendingDeletion() ? 'wt-old' : '' ?> overflow-hidden" data-wt-chart-xref="<?= e($individual->xref()) ?>" data-tree="<?= e($individual->tree()->name()) ?>">
101    <?php if ($individual->canShow() && $individual->tree()->getPreference('SHOW_HIGHLIGHT_IMAGES')) : ?>
102        <div class="wt-chart-box-thumbnail float-start me-1">
103            <?= $individual->displayImage(40, 50, 'crop', ['class' => 'wt-chart-box-thumbnail']) ?>
104        </div>
105    <?php endif ?>
106
107    <?php if ($individual->canShow()) : ?>
108        <div class="wt-chart-box-extra d-print-none float-end ms-1">
109            <div class="dropdown position-static wt-chart-box-zoom">
110                <a class="wt-chart-box-icon" href="#" role="button" id="chart-box-zoom-<?= $id ?>" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
111                    <div ><?= view('icons/zoom-in') ?></div>
112                    <div class="d-none"><?= view('icons/zoom-out') ?></div>
113                    <span class="visually-hidden"><?= I18N::translate('Links') ?></span>
114                </a>
115
116                <div class="dropdown-menu dropdown-menu-end wt-chart-box-dropdown wt-chart-box-zoom-dropdown" style="position: inherit" aria-labelledby="#chart-box-zoom-<?= $id ?>">
117                    <?php foreach ($all_facts as $fact) : ?>
118                        <?= $fact->summary() ?>
119                    <?php endforeach ?>
120                </div>
121            </div>
122
123            <div class="dropdown position-static wt-chart-box-links">
124                <a class="wt-chart-box-icon" href="#" role="button" id="chart-box-menu-<?= $id ?>" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
125                    <i class="icon-pedigree" title="<?= I18N::translate('Links') ?>"></i>
126                    <span class="visually-hidden"><?= I18N::translate('Links') ?></span>
127                </a>
128
129                <div class="dropdown-menu dropdown-menu-end wt-chart-box-dropdown wt-chart-box-links-dropdown" style="position: inherit" aria-labelledby="#chart-box-menu-<?= $id ?>">
130                    <?php foreach ($menus as $menu) : ?>
131                        <a class="dropdown-item p-1 <?= e($menu->getClass()) ?>" href="<?= e($menu->getLink()) ?>">
132                            <?= $menu->getLabel() ?>
133                        </a>
134                    <?php endforeach ?>
135                </div>
136            </div>
137        </div>
138    <?php endif ?>
139
140    <div class="wt-chart-box-name">
141        <?php if ($individual->canShow()) : ?>
142            <a href="<?= e($individual->url()) ?>"><?= $individual->fullName() ?></a>
143        <?php else : ?>
144            <?= $individual->fullName() ?>
145        <?php endif ?>
146    </div>
147
148    <div class="wt-chart-box-name wt-chart-box-name-alt">
149        <?= $individual->alternateName() ?>
150    </div>
151
152    <div class="wt-chart-box-lifespan">
153        <?= $individual->lifespan() ?>
154    </div>
155
156    <div class="wt-chart-box-facts">
157        <div class="wt-chart-box-fact small">
158            <?php
159            $opt_tags = preg_split('/\W/', $individual->tree()->getPreference('CHART_BOX_TAGS'), 0, PREG_SPLIT_NO_EMPTY);
160            // Show BIRT or equivalent event
161
162            foreach (Gedcom::BIRTH_EVENTS as $birttag) {
163                if (!in_array($birttag, $opt_tags, true)) {
164                    $event = $individual->facts([$birttag])->first();
165                    if ($event instanceof Fact) {
166                        echo $event->summary();
167                        break;
168                    }
169                }
170            }
171            // Show optional events (before death)
172            foreach ($opt_tags as $key => $tag) {
173                if (!in_array($tag, Gedcom::DEATH_EVENTS, true)) {
174                    $event = $individual->facts([$tag])->first();
175                    if ($event instanceof Fact) {
176                        echo $event->summary();
177                        unset($opt_tags[$key]);
178                    }
179                }
180            }
181            // Show DEAT or equivalent event
182            foreach (Gedcom::DEATH_EVENTS as $deattag) {
183                $event = $individual->facts([$deattag])->first();
184                if ($event instanceof Fact) {
185                    echo $event->summary();
186                    if (in_array($deattag, $opt_tags, true)) {
187                        unset($opt_tags[array_search($deattag, $opt_tags, true)]);
188                    }
189                    break;
190                }
191            }
192            // Show remaining optional events (after death)
193            foreach ($opt_tags as $tag) {
194                $event = $individual->facts([$tag])->first();
195                if ($event instanceof Fact) {
196                    echo $event->summary();
197                }
198            }
199            ?>
200        </div>
201    </div>
202</div>
203