Passed
Push — master ( d2ebda...80489a )
by Greg
05:54
created

FunctionsPrint::formatParentsAges()   C

Complexity

Conditions 12
Paths 3

Size

Total Lines 41
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 28
nc 3
nop 2
dl 0
loc 41
rs 6.9666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2019 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Functions;
21
22
use Fisharebest\Webtrees\Age;
23
use Fisharebest\Webtrees\Date;
24
use Fisharebest\Webtrees\Fact;
25
use Fisharebest\Webtrees\Family;
26
use Fisharebest\Webtrees\Filter;
27
use Fisharebest\Webtrees\Gedcom;
28
use Fisharebest\Webtrees\GedcomCode\GedcomCodeStat;
29
use Fisharebest\Webtrees\GedcomCode\GedcomCodeTemp;
30
use Fisharebest\Webtrees\GedcomRecord;
31
use Fisharebest\Webtrees\GedcomTag;
32
use Fisharebest\Webtrees\Header;
33
use Fisharebest\Webtrees\I18N;
34
use Fisharebest\Webtrees\Individual;
35
use Fisharebest\Webtrees\Media;
36
use Fisharebest\Webtrees\Note;
37
use Fisharebest\Webtrees\Place;
38
use Fisharebest\Webtrees\Repository;
39
use Fisharebest\Webtrees\Source;
40
use Fisharebest\Webtrees\Submission;
41
use Fisharebest\Webtrees\Submitter;
42
use Fisharebest\Webtrees\Tree;
43
use Illuminate\Support\Collection;
44
use Illuminate\Support\Str;
45
use LogicException;
46
use Ramsey\Uuid\Uuid;
47
48
use function array_filter;
49
use function array_intersect;
50
use function array_merge;
51
use function array_search;
52
use function e;
53
use function explode;
54
use function in_array;
55
use function preg_match;
56
use function preg_match_all;
57
use function preg_replace_callback;
58
use function preg_split;
59
use function strip_tags;
60
use function strlen;
61
use function strpos;
62
use function strtoupper;
63
use function substr;
64
use function trim;
65
use function uasort;
66
use function view;
67
68
use const PREG_SET_ORDER;
69
use const PREG_SPLIT_NO_EMPTY;
70
71
/**
72
 * Class FunctionsPrint - common functions
73
 */
74
class FunctionsPrint
75
{
76
    /**
77
     * print a note record
78
     *
79
     * @param Tree   $tree
80
     * @param string $text
81
     * @param int    $nlevel the level of the note record
82
     * @param string $nrec   the note record to print
83
     *
84
     * @return string
85
     */
86
    private static function printNoteRecord(Tree $tree, $text, $nlevel, $nrec): string
87
    {
88
        $text .= Functions::getCont($nlevel, $nrec);
89
90
        // Check if shared note (we have already checked that it exists)
91
        if (preg_match('/^0 @(' . Gedcom::REGEX_XREF . ')@ NOTE/', $nrec, $match)) {
92
            $note  = Note::getInstance($match[1], $tree);
93
            $label = 'SHARED_NOTE';
94
            $html  = Filter::formatText($note->getNote(), $tree);
95
        } else {
96
            $note  = null;
97
            $label = 'NOTE';
98
            $html  = Filter::formatText($text, $tree);
99
        }
100
101
        if (strpos($text, "\n") === false) {
102
            // A one-line note? strip the block-level tags, so it displays inline
103
            return GedcomTag::getLabelValue($label, strip_tags($html, '<a><strong><em>'));
104
        }
105
106
        if ($tree->getPreference('EXPAND_NOTES')) {
107
            // A multi-line note, and we're expanding notes by default
108
            return GedcomTag::getLabelValue($label, $html);
109
        }
110
111
        // A multi-line note, with an expand/collapse option
112
        $element_id = Uuid::uuid4()->toString();
113
        // NOTE: class "note-details" is (currently) used only by some third-party themes
114
        if ($note) {
115
            $first_line = '<a href="' . e($note->url()) . '">' . $note->fullName() . '</a>';
116
        } else {
117
            [$text] = explode("\n", strip_tags($html));
118
            $first_line = Str::limit($text, 100, I18N::translate('…'));
119
        }
120
121
        return
122
            '<div class="fact_NOTE"><span class="label">' .
123
            '<a href="#" onclick="expand_layer(\'' . $element_id . '\'); return false;"><i id="' . $element_id . '_img" class="icon-plus"></i></a> ' . GedcomTag::getLabel($label) . ':</span> ' . '<span id="' . $element_id . '-alt">' . $first_line . '</span>' .
124
            '</div>' .
125
            '<div class="note-details" id="' . $element_id . '" style="display:none">' . $html . '</div>';
126
    }
127
128
    /**
129
     * Print all of the notes in this fact record
130
     *
131
     * @param Tree   $tree
132
     * @param string $factrec The fact to print the notes from
133
     * @param int    $level   The level of the notes
134
     *
135
     * @return string HTML
136
     */
137
    public static function printFactNotes(Tree $tree, $factrec, $level): string
138
    {
139
        $data          = '';
140
        $previous_spos = 0;
141
        $nlevel        = $level + 1;
142
        $ct            = preg_match_all("/$level NOTE (.*)/", $factrec, $match, PREG_SET_ORDER);
143
        for ($j = 0; $j < $ct; $j++) {
144
            $spos1 = strpos($factrec, $match[$j][0], $previous_spos);
145
            $spos2 = strpos($factrec . "\n$level", "\n$level", $spos1 + 1);
146
            if (!$spos2) {
147
                $spos2 = strlen($factrec);
148
            }
149
            $previous_spos = $spos2;
150
            $nrec          = substr($factrec, $spos1, $spos2 - $spos1);
151
            if (!isset($match[$j][1])) {
152
                $match[$j][1] = '';
153
            }
154
            if (!preg_match('/^@(' . Gedcom::REGEX_XREF . ')@$/', $match[$j][1], $nmatch)) {
155
                $data .= self::printNoteRecord($tree, $match[$j][1], $nlevel, $nrec);
156
            } else {
157
                $note = Note::getInstance($nmatch[1], $tree);
158
                if ($note) {
159
                    if ($note->canShow()) {
160
                        $noterec = $note->gedcom();
161
                        $nt      = preg_match("/0 @$nmatch[1]@ NOTE (.*)/", $noterec, $n1match);
162
                        $data    .= self::printNoteRecord($tree, $nt > 0 ? $n1match[1] : '', 1, $noterec);
163
                    }
164
                } else {
165
                    $data = '<div class="fact_NOTE"><span class="label">' . I18N::translate('Note') . '</span>: <span class="field error">' . $nmatch[1] . '</span></div>';
166
                }
167
            }
168
        }
169
170
        return $data;
171
    }
172
173
    /**
174
     * Format age of parents in HTML
175
     *
176
     * @param Individual $person child
177
     * @param Date       $birth_date
178
     *
179
     * @return string HTML
180
     */
181
    public static function formatParentsAges(Individual $person, Date $birth_date): string
182
    {
183
        $html     = '';
184
        $families = $person->childFamilies();
185
        // Multiple sets of parents (e.g. adoption) cause complications, so ignore.
186
        if ($birth_date->isOK() && $families->count() === 1) {
187
            $family = $families->first();
188
            foreach ($family->spouses() as $parent) {
189
                if ($parent->getBirthDate()->isOK()) {
190
                    $sex      = '<small>' . view('icons/sex', ['sex' => $parent->sex()]) . '</small>';
191
                    $age      = new Age($parent->getBirthDate(), $birth_date);
192
                    $deatdate = $parent->getDeathDate();
193
                    switch ($parent->sex()) {
194
                        case 'F':
195
                            // Highlight mothers who die in childbirth or shortly afterwards
196
                            if ($deatdate->isOK() && $deatdate->maximumJulianDay() < $birth_date->minimumJulianDay() + 90) {
197
                                $html .= ' <span title="' . GedcomTag::getLabel('_DEAT_PARE', $parent) . '" class="parentdeath">' . $sex . I18N::number($age->ageYears()) . '</span>';
198
                            } else {
199
                                $html .= ' <span title="' . I18N::translate('Mother’s age') . '">' . $sex . I18N::number($age->ageYears()) . '</span>';
200
                            }
201
                            break;
202
                        case 'M':
203
                            // Highlight fathers who die before the birth
204
                            if ($deatdate->isOK() && $deatdate->maximumJulianDay() < $birth_date->minimumJulianDay()) {
205
                                $html .= ' <span title="' . GedcomTag::getLabel('_DEAT_PARE', $parent) . '" class="parentdeath">' . $sex . I18N::number($age->ageYears()) . '</span>';
206
                            } else {
207
                                $html .= ' <span title="' . I18N::translate('Father’s age') . '">' . $sex . I18N::number($age->ageYears()) . '</span>';
208
                            }
209
                            break;
210
                        default:
211
                            $html .= ' <span title="' . I18N::translate('Parent’s age') . '">' . $sex . I18N::number($age->ageYears()) . '</span>';
212
                            break;
213
                    }
214
                }
215
            }
216
            if ($html) {
217
                $html = '<span class="age">' . $html . '</span>';
218
            }
219
        }
220
221
        return $html;
222
    }
223
224
    /**
225
     * Convert a GEDCOM age string to localized text.
226
     *
227
     * @param string $age_string
228
     *
229
     * @return string
230
     */
231
    public static function formatGedcomAge(string $age_string): string
232
    {
233
        switch (strtoupper($age_string)) {
234
            case 'CHILD':
235
                return I18N::translate('Child');
236
            case 'INFANT':
237
                return I18N::translate('Infant');
238
            case 'STILLBORN':
239
                return I18N::translate('Stillborn');
240
            default:
241
                return preg_replace_callback(
242
                    [
243
                        '/(\d+)([ymwd])/',
244
                    ],
245
                    static function (array $match): string {
246
                        $num = (int) $match[1];
247
248
                        switch ($match[2]) {
249
                            case 'y':
250
                                return I18N::plural('%s year', '%s years', $num, I18N::number($num));
251
                            case 'm':
252
                                return I18N::plural('%s month', '%s months', $num, I18N::number($num));
253
                            case 'w':
254
                                return I18N::plural('%s week', '%s weeks', $num, I18N::number($num));
255
                            case 'd':
256
                                return I18N::plural('%s day', '%s days', $num, I18N::number($num));
257
                            default:
258
                                throw new LogicException('Should never get here');
259
                        }
260
                    },
261
                    $age_string
262
                ) ;
263
        }
264
    }
265
266
    /**
267
     * Print fact DATE/TIME
268
     *
269
     * @param Fact         $event  event containing the date/age
270
     * @param GedcomRecord $record the person (or couple) whose ages should be printed
271
     * @param bool         $anchor option to print a link to calendar
272
     * @param bool         $time   option to print TIME value
273
     *
274
     * @return string
275
     */
276
    public static function formatFactDate(Fact $event, GedcomRecord $record, $anchor, $time): string
277
    {
278
        $factrec = $event->gedcom();
279
        $html    = '';
280
        // Recorded age
281
        if (preg_match('/\n2 AGE (.+)/', $factrec, $match)) {
282
            $fact_age = self::formatGedcomAge($match[1]);
283
        } else {
284
            $fact_age = '';
285
        }
286
        if (preg_match('/\n2 HUSB\n3 AGE (.+)/', $factrec, $match)) {
287
            $husb_age = self::formatGedcomAge($match[1]);
288
        } else {
289
            $husb_age = '';
290
        }
291
        if (preg_match('/\n2 WIFE\n3 AGE (.+)/', $factrec, $match)) {
292
            $wife_age = self::formatGedcomAge($match[1]);
293
        } else {
294
            $wife_age = '';
295
        }
296
297
        // Calculated age
298
        $fact = $event->getTag();
299
        if (preg_match('/\n2 DATE (.+)/', $factrec, $match)) {
300
            $date = new Date($match[1]);
301
            $html .= ' ' . $date->display($anchor);
302
            // time
303
            if ($time && preg_match('/\n3 TIME (.+)/', $factrec, $match)) {
304
                $html .= ' – <span class="date">' . $match[1] . '</span>';
305
            }
306
            if ($record instanceof Individual) {
307
                if (in_array($fact, Gedcom::BIRTH_EVENTS, true) && $record->tree()->getPreference('SHOW_PARENTS_AGE')) {
308
                    // age of parents at child birth
309
                    $html .= self::formatParentsAges($record, $date);
310
                }
311
                if ($fact !== 'BIRT' && $fact !== 'CHAN' && $fact !== '_TODO') {
312
                    // age at event
313
                    $birth_date = $record->getBirthDate();
314
                    // Can't use getDeathDate(), as this also gives BURI/CREM events, which
315
                    // wouldn't give the correct "days after death" result for people with
316
                    // no DEAT.
317
                    $death_event = $record->facts(['DEAT'])->first();
318
                    if ($death_event instanceof Fact) {
319
                        $death_date = $death_event->date();
320
                    } else {
321
                        $death_date = new Date('');
322
                    }
323
                    $ageText = '';
324
                    if ($fact === 'DEAT' || Date::compare($date, $death_date) <= 0 || !$record->isDead()) {
325
                        // Before death, print age
326
                        $age = (new Age($birth_date, $date))->ageAtEvent(false);
327
                        // Only show calculated age if it differs from recorded age
328
                        if ($age !== '') {
329
                            if ($fact_age !== '' && $fact_age !== $age) {
330
                                $ageText = $age;
331
                            } elseif ($fact_age === '' && $husb_age === '' && $wife_age === '') {
332
                                $ageText = $age;
333
                            } elseif ($husb_age !== '' && $husb_age !== $age && $record->sex() === 'M') {
334
                                $ageText = $age;
335
                            } elseif ($wife_age !== '' && $wife_age !== $age && $record->sex() === 'F') {
336
                                $ageText = $age;
337
                            }
338
                        }
339
                    }
340
                    if ($fact !== 'DEAT' && Date::compare($death_date, $date) <= 0) {
341
                        // After death, print time since death
342
                        $ageText = (new Age($death_date, $date))->timeAfterDeath();
343
                        // Family events which occur after death are probably errors
344
                        if ($event->record() instanceof Family) {
345
                            $ageText .= view('icons/warning');
346
                        }
347
                    }
348
                    if ($ageText) {
349
                        $html .= ' <span class="age">' . $ageText . '</span>';
350
                    }
351
                }
352
            }
353
        }
354
        // print gedcom ages
355
        $age_labels = [
356
            I18N::translate('Age')     => $fact_age,
357
            I18N::translate('Husband') => $husb_age,
358
            I18N::translate('Wife')    => $wife_age,
359
        ];
360
361
        foreach (array_filter($age_labels) as $label => $age) {
362
            $html .= ' <span class="label">' . $label . ':</span> <span class="age">' . $age . '</span>';
363
        }
364
365
        return $html;
366
    }
367
368
    /**
369
     * print fact PLACe TEMPle STATus
370
     *
371
     * @param Fact $event       gedcom fact record
372
     * @param bool $anchor      to print a link to placelist
373
     * @param bool $sub_records to print place subrecords
374
     * @param bool $lds         to print LDS TEMPle and STATus
375
     *
376
     * @return string HTML
377
     */
378
    public static function formatFactPlace(Fact $event, $anchor = false, $sub_records = false, $lds = false): string
379
    {
380
        $tree = $event->record()->tree();
381
382
        if ($anchor) {
383
            // Show the full place name, for facts/events tab
384
            $html = $event->place()->fullName(true);
385
        } else {
386
            // Abbreviate the place name, for chart boxes
387
            return $event->place()->shortName();
388
        }
389
390
        if ($sub_records) {
391
            $placerec = Functions::getSubRecord(2, '2 PLAC', $event->gedcom());
392
            if ($placerec !== '') {
393
                if (preg_match_all('/\n3 (?:_HEB|ROMN) (.+)/', $placerec, $matches)) {
394
                    foreach ($matches[1] as $match) {
395
                        $wt_place = new Place($match, $tree);
396
                        $html     .= ' - ' . $wt_place->fullName();
397
                    }
398
                }
399
                $map_lati = '';
400
                $cts      = preg_match('/\d LATI (.*)/', $placerec, $match);
401
                if ($cts > 0) {
402
                    $map_lati = $match[1];
403
                    $html     .= '<br><span class="label">' . I18N::translate('Latitude') . ': </span>' . $map_lati;
404
                }
405
                $map_long = '';
406
                $cts      = preg_match('/\d LONG (.*)/', $placerec, $match);
407
                if ($cts > 0) {
408
                    $map_long = $match[1];
409
                    $html     .= ' <span class="label">' . I18N::translate('Longitude') . ': </span>' . $map_long;
410
                }
411
                if ($map_lati && $map_long) {
412
                    $map_lati = trim(strtr($map_lati, 'NSEW,�', ' - -. ')); // S5,6789 ==> -5.6789
413
                    $map_long = trim(strtr($map_long, 'NSEW,�', ' - -. ')); // E3.456� ==> 3.456
414
415
                    $html .= '<a href="https://maps.google.com/maps?q=' . e($map_lati) . ',' . e($map_long) . '" rel="nofollow" title="' . I18N::translate('Google Maps™') . '">' .
416
                        view('icons/google-maps') .
417
                        '<span class="sr-only">' . I18N::translate('Google Maps™') . '</span>' .
418
                        '</a>';
419
420
                    $html .= '<a href="https://www.bing.com/maps/?lvl=15&cp=' . e($map_lati) . '~' . e($map_long) . '" rel="nofollow" title="' . I18N::translate('Bing Maps™') . '">' .
421
                        view('icons/bing-maps') .
422
                        '<span class="sr-only">' . I18N::translate('Bing Maps™') . '</span>' .
423
                        '</a>';
424
425
                    $html .= '<a href="https://www.openstreetmap.org/#map=15/' . e($map_lati) . '/' . e($map_long) . '" rel="nofollow" title="' . I18N::translate('OpenStreetMap™') . '">' .
426
                        view('icons/openstreetmap') .
427
                        '<span class="sr-only">' . I18N::translate('OpenStreetMap™') . '</span>' .
428
                        '</a>';
429
                }
430
                if (preg_match('/\d NOTE (.*)/', $placerec, $match)) {
431
                    $html .= '<br>' . self::printFactNotes($tree, $placerec, 3);
432
                }
433
            }
434
        }
435
        if ($lds) {
436
            if (preg_match('/2 TEMP (.*)/', $event->gedcom(), $match)) {
437
                $html .= '<br>' . I18N::translate('LDS temple') . ': ' . GedcomCodeTemp::templeName($match[1]);
438
            }
439
            if (preg_match('/2 STAT (.*)/', $event->gedcom(), $match)) {
440
                $html .= '<br>' . I18N::translate('Status') . ': ' . GedcomCodeStat::statusName($match[1]);
441
                if (preg_match('/3 DATE (.*)/', $event->gedcom(), $match)) {
442
                    $date = new Date($match[1]);
443
                    $html .= ', ' . GedcomTag::getLabel('STAT:DATE') . ': ' . $date->display();
444
                }
445
            }
446
        }
447
448
        return $html;
449
    }
450
451
    /**
452
     * Check for facts that may exist only once for a certain record type.
453
     * If the fact already exists in the second array, delete it from the first one.
454
     *
455
     * @param string[]   $uniquefacts
456
     * @param Collection $recfacts
457
     *
458
     * @return string[]
459
     */
460
    public static function checkFactUnique(array $uniquefacts, Collection $recfacts): array
461
    {
462
        foreach ($recfacts as $factarray) {
463
            $fact = $factarray->getTag();
464
465
            $key = array_search($fact, $uniquefacts, true);
466
            if ($key !== false) {
467
                unset($uniquefacts[$key]);
468
            }
469
        }
470
471
        return $uniquefacts;
472
    }
473
474
    /**
475
     * Print a new fact box on details pages
476
     *
477
     * @param GedcomRecord $record    the person, family, source etc the fact will be added to
478
     * @param Collection   $usedfacts an array of facts already used in this record
479
     * @param string       $type      the type of record INDI, FAM, SOUR etc
480
     *
481
     * @return void
482
     */
483
    public static function printAddNewFact(GedcomRecord $record, Collection $usedfacts, $type): void
484
    {
485
        $tree = $record->tree();
486
487
        // -- Add from pick list
488
        switch ($type) {
489
            case Individual::RECORD_TYPE:
490
                $addfacts    = preg_split('/[, ;:]+/', $tree->getPreference('INDI_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY);
491
                $uniquefacts = preg_split('/[, ;:]+/', $tree->getPreference('INDI_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY);
492
                $quickfacts  = preg_split('/[, ;:]+/', $tree->getPreference('INDI_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY);
493
                break;
494
495
            case Family::RECORD_TYPE:
496
                $addfacts    = preg_split('/[, ;:]+/', $tree->getPreference('FAM_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY);
497
                $uniquefacts = preg_split('/[, ;:]+/', $tree->getPreference('FAM_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY);
498
                $quickfacts  = preg_split('/[, ;:]+/', $tree->getPreference('FAM_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY);
499
                break;
500
501
            case Source::RECORD_TYPE:
502
                $addfacts    = preg_split('/[, ;:]+/', $tree->getPreference('SOUR_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY);
503
                $uniquefacts = preg_split('/[, ;:]+/', $tree->getPreference('SOUR_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY);
504
                $quickfacts  = preg_split('/[, ;:]+/', $tree->getPreference('SOUR_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY);
505
                break;
506
507
            case Note::RECORD_TYPE:
508
                $addfacts    = preg_split('/[, ;:]+/', $tree->getPreference('NOTE_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY);
509
                $uniquefacts = preg_split('/[, ;:]+/', $tree->getPreference('NOTE_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY);
510
                $quickfacts  = preg_split('/[, ;:]+/', $tree->getPreference('NOTE_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY);
511
                break;
512
513
            case Repository::RECORD_TYPE:
514
                $addfacts    = preg_split('/[, ;:]+/', $tree->getPreference('REPO_FACTS_ADD'), -1, PREG_SPLIT_NO_EMPTY);
515
                $uniquefacts = preg_split('/[, ;:]+/', $tree->getPreference('REPO_FACTS_UNIQUE'), -1, PREG_SPLIT_NO_EMPTY);
516
                $quickfacts  = preg_split('/[, ;:]+/', $tree->getPreference('REPO_FACTS_QUICK'), -1, PREG_SPLIT_NO_EMPTY);
517
                break;
518
519
            case Media::RECORD_TYPE:
520
                $addfacts    = ['NOTE'];
521
                $uniquefacts = [];
522
                $quickfacts  = [];
523
                break;
524
525
            case Submitter::RECORD_TYPE:
526
                $addfacts    = ['LANG', 'OBJE', 'NOTE', 'SHARED_NOTE'];
527
                $uniquefacts = ['ADDR', 'EMAIL', 'NAME', 'PHON', 'WWW'];
528
                $quickfacts  = [];
529
                break;
530
531
            case Submission::RECORD_TYPE:
532
                $addfacts    = ['NOTE', 'SHARED_NOTE'];
533
                $uniquefacts = ['FAMF', 'TEMP', 'ANCE', 'DESC', 'ORDI', 'SUBM'];
534
                $quickfacts  = [];
535
                break;
536
537
            case Header::RECORD_TYPE:
538
                $addfacts    = [];
539
                $uniquefacts = ['COPR', 'LANG', 'SUBM'];
540
                $quickfacts  = [];
541
                break;
542
            default:
543
                return;
544
        }
545
        $addfacts            = array_merge(self::checkFactUnique($uniquefacts, $usedfacts), $addfacts);
546
        $quickfacts          = array_intersect($quickfacts, $addfacts);
547
        $translated_addfacts = [];
548
        foreach ($addfacts as $addfact) {
549
            $translated_addfacts[$addfact] = GedcomTag::getLabel($addfact);
550
        }
551
        uasort($translated_addfacts, static function (string $x, string $y): int {
552
            return I18N::strcasecmp(I18N::translate($x), I18N::translate($y));
553
        });
554
555
        echo view('edit/add-fact-row', [
556
            'add_facts'   => $translated_addfacts,
557
            'quick_facts' => $quickfacts,
558
            'record'      => $record,
559
            'tree'        => $tree,
560
        ]);
561
    }
562
}
563