summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
authorGreg Roach <greg@subaqua.co.uk>2022-02-05 14:07:42 +0000
committerGreg Roach <greg@subaqua.co.uk>2022-02-11 09:10:04 +0000
commitb315f3e1bccd89f38d8ab5d44d3cc6327d590a57 (patch)
tree713e7a727563acff6708648cfd23edbcd7a5b2a6 /resources
parent6191ab59bd50c724ad4634cd32a946fe3b996251 (diff)
downloadwebtrees-b315f3e1bccd89f38d8ab5d44d3cc6327d590a57.tar.gz
webtrees-b315f3e1bccd89f38d8ab5d44d3cc6327d590a57.tar.bz2
webtrees-b315f3e1bccd89f38d8ab5d44d3cc6327d590a57.zip
Fix: #1584 - Replace FunctionsPrint* with templates
Diffstat (limited to 'resources')
-rwxr-xr-xresources/css/clouds.css13
-rwxr-xr-xresources/css/fab.css13
-rwxr-xr-xresources/css/minimal.css7
-rwxr-xr-xresources/css/webtrees.css14
-rwxr-xr-xresources/css/xenea.css13
-rw-r--r--resources/views/edit/edit-gedcom-fields.phtml4
-rw-r--r--resources/views/edit/icon-fact-edit.phtml3
-rw-r--r--resources/views/fact-add-new.phtml99
-rw-r--r--resources/views/fact-associates.phtml13
-rw-r--r--resources/views/fact-association-structure.phtml107
-rw-r--r--resources/views/fact-date.phtml149
-rw-r--r--resources/views/fact-edit-links.phtml17
-rw-r--r--resources/views/fact-gedcom-fields.phtml67
-rw-r--r--resources/views/fact-media.phtml17
-rw-r--r--resources/views/fact-notes.phtml17
-rw-r--r--resources/views/fact-parent-age.phtml44
-rw-r--r--resources/views/fact-parents-age.phtml29
-rw-r--r--resources/views/fact-place.phtml57
-rw-r--r--resources/views/fact-sources.phtml17
-rw-r--r--resources/views/fact.phtml158
-rw-r--r--resources/views/family-page.phtml9
-rw-r--r--resources/views/individual-name.phtml8
-rw-r--r--resources/views/individual-sex.phtml8
-rw-r--r--resources/views/media-page-details.phtml5
-rw-r--r--resources/views/modules/media-list/page.phtml13
-rw-r--r--resources/views/modules/media/tab.phtml42
-rw-r--r--resources/views/modules/notes/tab.phtml56
-rw-r--r--resources/views/modules/personal_facts/tab.phtml6
-rw-r--r--resources/views/modules/random_media/slide-show.phtml5
-rw-r--r--resources/views/modules/sources_tab/tab.phtml33
-rw-r--r--resources/views/modules/timeline-chart/chart.phtml3
-rw-r--r--resources/views/note-page-details.phtml5
-rw-r--r--resources/views/record-page-details.phtml3
33 files changed, 940 insertions, 114 deletions
diff --git a/resources/css/clouds.css b/resources/css/clouds.css
index f5800e2fb4..d03eaffa26 100755
--- a/resources/css/clouds.css
+++ b/resources/css/clouds.css
@@ -913,12 +913,6 @@ div.fact_SHARED_NOTE {
width: 70%;
}
-/* this keeps the tag color the same when it is a link as when not */
-
-.place {
- padding-top: 5px;
-}
-
.filtersH,
.filtersF {
margin: 4px;
@@ -977,13 +971,6 @@ div.faq_body {
float: right;
}
-/* === Positioning edit, copy, delete links === */
-/* General use */
-.editfacts {
- clear: left;
- padding-top: 15px;
-}
-
#indi_note {
margin: 0 0 5px;
}
diff --git a/resources/css/fab.css b/resources/css/fab.css
index 27ddc7e053..7dab9493ef 100755
--- a/resources/css/fab.css
+++ b/resources/css/fab.css
@@ -667,12 +667,6 @@ div.fact_SHARED_NOTE {
width: 70%;
}
-/* this keeps the tag color the same when it is a link as when not */
-
-.place {
- padding-top: 5px;
-}
-
.filtersH,
.filtersF {
margin: 4px;
@@ -731,13 +725,6 @@ div.faq_body {
float: right;
}
-/* === Positioning edit, copy, delete links === */
-/* General use */
-.editfacts {
- clear: left;
- padding-top: 15px;
-}
-
#indi_note {
margin: 0 0 5px;
}
diff --git a/resources/css/minimal.css b/resources/css/minimal.css
index 040c1f9709..fd820758d1 100755
--- a/resources/css/minimal.css
+++ b/resources/css/minimal.css
@@ -450,13 +450,6 @@ div.faq_body {
float: right;
}
-/* === Positioning edit, copy, delete links === */
-/* General use */
-.editfacts {
- clear: left;
- padding-top: 15px;
-}
-
#indi_note {
margin: 0 0 5px;
}
diff --git a/resources/css/webtrees.css b/resources/css/webtrees.css
index 1dae5a0c9e..798c7dc5ec 100755
--- a/resources/css/webtrees.css
+++ b/resources/css/webtrees.css
@@ -868,12 +868,6 @@ td.descriptionbox a {
color: #fff;
}
-/* this keeps the tag color the same when it is a link as when not */
-
-.place {
- padding-top: 5px;
-}
-
.filtersH,
.filtersF {
margin: 4px;
@@ -920,13 +914,6 @@ div.faq_body {
float: right;
}
-/* === Positioning edit, copy, delete links === */
-/* General use */
-.editfacts {
- clear: left;
- padding-top: 15px;
-}
-
#indi_note {
margin: 0 0 5px;
}
@@ -1079,7 +1066,6 @@ div.faq_body {
}
.wt-lifespans-individual {
-
}
.wt-lifespans-summary {
diff --git a/resources/css/xenea.css b/resources/css/xenea.css
index d2577a96ab..8ea42cafd0 100755
--- a/resources/css/xenea.css
+++ b/resources/css/xenea.css
@@ -856,12 +856,6 @@ div.fact_SHARED_NOTE {
width: 70%;
}
-/* this keeps the tag color the same when it is a link as when not */
-
-.place {
- padding-top: 5px;
-}
-
.filtersH,
.filtersF {
margin: 4px;
@@ -908,13 +902,6 @@ div.faq_body {
float: right;
}
-/* === Positioning edit, copy, delete links === */
-/* General use */
-.editfacts {
- clear: left;
- padding-top: 15px;
-}
-
#indi_note {
margin: 0 0 5px;
}
diff --git a/resources/views/edit/edit-gedcom-fields.phtml b/resources/views/edit/edit-gedcom-fields.phtml
index dfffef6dfd..da6d2dd793 100644
--- a/resources/views/edit/edit-gedcom-fields.phtml
+++ b/resources/views/edit/edit-gedcom-fields.phtml
@@ -21,7 +21,7 @@ $ids = [];
$indent = [];
$collapse = [];
-foreach ($keys as $key) {
+foreach ($keys as $num => $key) {
$hierarchy[$levels[$key]] = $tags[$key];
$full_tag = implode(':', array_slice($hierarchy, 0, 1 + $levels[$key]));
$elements[$key] = Registry::elementFactory()->make($full_tag);
@@ -41,7 +41,7 @@ foreach ($keys as $key) {
$indent[$key] = $elements[$key]->collapseChildren() && $has_subtags;
- $collapse[$key] = $indent[$key] && !$has_subtags_with_values;
+ $collapse[$key] = $num > 0 && $indent[$key] && !$has_subtags_with_values;
}
?>
diff --git a/resources/views/edit/icon-fact-edit.phtml b/resources/views/edit/icon-fact-edit.phtml
index 383e531266..8d25225991 100644
--- a/resources/views/edit/icon-fact-edit.phtml
+++ b/resources/views/edit/icon-fact-edit.phtml
@@ -5,7 +5,8 @@ use Fisharebest\Webtrees\Http\RequestHandlers\EditFactPage;
use Fisharebest\Webtrees\I18N;
/**
- * @var Fact $fact
+ * @var Fact $fact
+ * @var string|null $url
*/
?>
diff --git a/resources/views/fact-add-new.phtml b/resources/views/fact-add-new.phtml
new file mode 100644
index 0000000000..cf9be3e902
--- /dev/null
+++ b/resources/views/fact-add-new.phtml
@@ -0,0 +1,99 @@
+<?php
+
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\Family;
+use Fisharebest\Webtrees\GedcomRecord;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Individual;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\GedcomEditService;
+
+/**
+ * @var GedcomRecord $record
+ */
+
+?>
+
+<?php
+$add_facts = (new GedcomEditService())->factsToAdd($record, false);
+
+// Add from pick list
+switch ($record->tag()) {
+ case Individual::RECORD_TYPE:
+ $quick_facts = explode(',', $record->tree()->getPreference('INDI_FACTS_QUICK'));
+ $unique_facts = [
+ 'ADOP',
+ 'AFN',
+ 'BAPL',
+ 'BAPM',
+ 'BARM',
+ 'BASM',
+ 'BIRT',
+ 'BURI',
+ 'CAST',
+ 'CHAN',
+ 'CHR',
+ 'CHRA',
+ 'CONF',
+ 'CONL',
+ 'CREM',
+ 'DEAT',
+ 'ENDL',
+ 'FCOM',
+ 'GRAD',
+ 'NCHI',
+ 'NMR',
+ 'ORDN',
+ 'PROB',
+ 'REFN',
+ 'RELI',
+ 'RESN',
+ 'RETI',
+ 'RFN',
+ 'RIN',
+ 'SEX',
+ 'SLGC',
+ 'SSN',
+ 'WILL',
+ ];
+ break;
+
+ case Family::RECORD_TYPE:
+ $quick_facts = explode(',', $record->tree()->getPreference('FAM_FACTS_QUICK'));
+ $unique_facts = [
+ 'DIV',
+ 'DIVF',
+ 'ENGA',
+ 'MARR',
+ ];
+ break;
+
+ default:
+ $quick_facts = [];
+ $unique_facts = [];
+ break;
+}
+
+// Filter existing tags
+$filter_fn = static fn (string $tag): bool => !in_array($tag, $unique_facts, true) || $record->facts([$tag])->isEmpty();
+
+$quick_facts = array_filter($quick_facts, $filter_fn);
+
+
+// Create a label for a subtag
+$label_fn = static fn (string $subtag): string => Registry::elementFactory()->make($record->tag() . ':' . $subtag)->label();
+
+$quick_facts = array_combine($quick_facts, array_map($label_fn, $quick_facts));
+$add_facts = array_combine($add_facts, array_map($label_fn, $add_facts));
+
+uasort($add_facts, I18N::comparator());
+
+if (!Auth::canUploadMedia($record->tree(), Auth::user())) {
+ unset($add_facts['OBJE'], $quick_facts['OBJE']);
+}
+
+echo view('edit/add-fact-row', [
+ 'add_facts' => $add_facts,
+ 'quick_facts' => $quick_facts,
+ 'record' => $record,
+]); \ No newline at end of file
diff --git a/resources/views/fact-associates.phtml b/resources/views/fact-associates.phtml
new file mode 100644
index 0000000000..8c96389084
--- /dev/null
+++ b/resources/views/fact-associates.phtml
@@ -0,0 +1,13 @@
+<?php
+
+use Fisharebest\Webtrees\Fact;
+
+/**
+ * @var Fact $fact
+ */
+
+?>
+
+<div class="wt-fact-associates mt-2">
+ <?= view('fact-association-structure', ['fact' => $fact]) ?>
+</div> \ No newline at end of file
diff --git a/resources/views/fact-association-structure.phtml b/resources/views/fact-association-structure.phtml
new file mode 100644
index 0000000000..c5d264558d
--- /dev/null
+++ b/resources/views/fact-association-structure.phtml
@@ -0,0 +1,107 @@
+<?php
+
+use Fisharebest\Webtrees\Age;
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\Fact;
+use Fisharebest\Webtrees\Family;
+use Fisharebest\Webtrees\Gedcom;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Individual;
+use Fisharebest\Webtrees\Module\ModuleChartInterface;
+use Fisharebest\Webtrees\Module\ModuleInterface;
+use Fisharebest\Webtrees\Module\RelationshipsChartModule;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\ModuleService;
+use Fisharebest\Webtrees\Services\RelationshipService;
+
+/**
+ * @var Fact $fact
+ */
+
+$parent = $fact->record();
+// To whom is this record an associate?
+if ($parent instanceof Individual) {
+ // On an individual page, we just show links to the person
+ $associates = [$parent];
+} elseif ($parent instanceof Family) {
+ // On a family page, we show links to both spouses
+ $associates = $parent->spouses();
+} else {
+ // On other pages, it does not make sense to show associates
+ return '';
+}
+
+preg_match_all('/\n2 (_?ASSO) @(' . Gedcom::REGEX_XREF . ')@((\n[3-9].*)*)/', $fact->gedcom(), $amatches, PREG_SET_ORDER);
+
+$html = '';
+// For each ASSO record
+foreach ($amatches as $amatch) {
+ $person = Registry::individualFactory()->make($amatch[2], $fact->record()->tree());
+ if ($person && $person->canShowName()) {
+ // Is there a "RELA" tag
+ if (preg_match('/\n([23]) RELA (.+)/', $amatch[3], $rmatch)) {
+ if ($rmatch[1] === '2') {
+ $rela_tag = $fact->record()->tag() . ':' . $amatch[1] . ':RELA';
+ } else {
+ $rela_tag = $fact->tag() . ':' . $amatch[1] . ':RELA';
+ }
+ // Use the supplied relationship as a label
+ $label = Registry::elementFactory()->make($rela_tag)->value($rmatch[2], $parent->tree());
+ } elseif (preg_match('/^1 _?ASSO/', $fact->gedcom())) {
+ // Use a default label
+ $label = Registry::elementFactory()->make($fact->tag())->label();
+ } else {
+ // Use a default label
+ $label = Registry::elementFactory()->make($fact->tag() . ':_ASSO')->label();
+ }
+
+ if ($person->getBirthDate()->isOK() && $fact->date()->isOK()) {
+ $age = new Age($person->getBirthDate(), $fact->date());
+ switch ($person->sex()) {
+ case 'M':
+ $age_text = ' ' . I18N::translateContext('Male', '(aged %s)', (string) $age);
+ break;
+ case 'F':
+ $age_text = ' ' . I18N::translateContext('Female', '(aged %s)', (string) $age);
+ break;
+ default:
+ $age_text = ' ' . I18N::translate('(aged %s)', (string) $age);
+ break;
+ }
+ } else {
+ $age_text = '';
+ }
+
+ $values = ['<a href="' . e($person->url()) . '">' . $person->fullName() . '</a>' . $age_text];
+
+ $module = app(ModuleService::class)->findByComponent(ModuleChartInterface::class, $person->tree(), Auth::user())->first(static function (ModuleInterface $module) {
+ return $module instanceof RelationshipsChartModule;
+ });
+
+ if ($module instanceof RelationshipsChartModule) {
+ foreach ($associates as $associate) {
+ $relationship_name = app(RelationshipService::class)->getCloseRelationshipName($associate, $person);
+ if ($relationship_name === '') {
+ $relationship_name = I18N::translate('Relationship');
+ }
+
+ if ($parent instanceof Family) {
+ // For family ASSO records (e.g. MARR), identify the spouse with a sex icon
+ $relationship_name .= '<small>' . view('icons/sex', ['sex' => $associate->sex()]) . '</small>';
+ }
+
+ $values[] = '<a href="' . $module->chartUrl($associate, ['xref2' => $person->xref()]) . '" rel="nofollow">' . $relationship_name . '</a>';
+ }
+ }
+ $value = implode(' — ', $values);
+ $asso = I18N::translate('<span class="label">%1$s:</span> <span class="field" dir="auto">%2$s</span>', $label, $value);
+ } elseif (!$person && Auth::isEditor($fact->record()->tree())) {
+ $value = '<span class="error">' . $amatch[2] . '</span>';
+ $asso = I18N::translate('<span class="label">%1$s:</span> <span class="field" dir="auto">%2$s</span>', I18N::translate('Associate'), $value);
+ } else {
+ $asso = '';
+ }
+ $html .= '<div class="fact_ASSO">' . $asso . '</div>';
+}
+
+echo $html;
diff --git a/resources/views/fact-date.phtml b/resources/views/fact-date.phtml
new file mode 100644
index 0000000000..35c97753b1
--- /dev/null
+++ b/resources/views/fact-date.phtml
@@ -0,0 +1,149 @@
+<?php
+
+use Fisharebest\Webtrees\Age;
+use Fisharebest\Webtrees\Date;
+use Fisharebest\Webtrees\Fact;
+use Fisharebest\Webtrees\Family;
+use Fisharebest\Webtrees\Gedcom;
+use Fisharebest\Webtrees\GedcomRecord;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Individual;
+use Fisharebest\Webtrees\Registry;
+
+/**
+ * @var bool $cal_link
+ * @var Fact $fact
+ * @var GedcomRecord $record
+ * @var bool $time
+ */
+
+$element_factory = Registry::elementFactory();
+
+$factrec = $fact->gedcom();
+$html = '';
+
+// Recorded age
+if (preg_match('/\n2 AGE (.+)/', $factrec, $match)) {
+ $fact_age = $element_factory->make($fact->tag() . ':AGE')->value($match[1], $record->tree());
+} else {
+ $fact_age = '';
+}
+
+if (preg_match('/\n2 HUSB\n3 AGE (.+)/', $factrec, $match)) {
+ $husb_age = $element_factory->make($fact->tag() . ':HUSB:AGE')->value($match[1], $record->tree());
+} else {
+ $husb_age = '';
+}
+
+if (preg_match('/\n2 WIFE\n3 AGE (.+)/', $factrec, $match)) {
+ $wife_age = $element_factory->make($fact->tag() . ':WIFE:AGE')->value($match[1], $record->tree());
+} else {
+ $wife_age = '';
+}
+
+// Calculated age
+[, $tag] = explode(':', $fact->tag());
+
+if (preg_match('/\n2 DATE (.+)/', $factrec, $match)) {
+ $date = new Date($match[1]);
+ $html .= ' ' . $date->display($cal_link ? $record->tree() : null, null, true);
+ // Time isn't valid GEDCOM, but it is widely used.
+ if ($time && preg_match('/\n3 TIME (.+)/', $factrec, $match)) {
+ $html .= ' – <span class="date">' . $match[1] . '</span>';
+ }
+
+ if ($record instanceof Individual) {
+ if (
+ in_array($tag, Gedcom::BIRTH_EVENTS, true) &&
+ $record === $fact->record() &&
+ $record->tree()->getPreference('SHOW_PARENTS_AGE') === '1'
+ ) {
+ // age of parents at child birth
+ $html .= view('fact-parents-age', ['individual' => $record, 'birth_date' => $date]);
+ }
+
+ if ($tag !== 'BIRT' && $tag !== 'CHAN' && $tag !== '_TODO') {
+ // age at event
+ $birth_date = $record->getBirthDate();
+ // Can't use getDeathDate(), as this also gives BURI/CREM events, which
+ // wouldn't give the correct "days after death" result for people with
+ // no DEAT.
+ $death_event = $record->facts(['DEAT'])->first();
+ if ($death_event instanceof Fact) {
+ $death_date = $death_event->date();
+ } else {
+ $death_date = new Date('');
+ }
+ $ageText = '';
+
+ if ($tag === 'DEAT' || Date::compare($date, $death_date) <= 0 || !$record->isDead()) {
+ // Before death, print age
+ $age = (string) new Age($birth_date, $date);
+
+ // Only show calculated age if it differs from recorded age
+ if ($age !== '') {
+ if (
+ $fact_age !== '' && !str_starts_with($fact_age, $age) ||
+ $fact_age === '' && $husb_age === '' && $wife_age === '' ||
+ $husb_age !== '' && !str_starts_with($husb_age, $age) && $record->sex() === 'M' ||
+ $wife_age !== '' && !str_starts_with($wife_age, $age) && $record->sex() === 'F'
+ ) {
+ switch ($record->sex()) {
+ case 'M':
+ /* I18N: The age of an individual at a given date */
+ $ageText = I18N::translateContext('Male', '(aged %s)', $age);
+ break;
+ case 'F':
+ /* I18N: The age of an individual at a given date */
+ $ageText = I18N::translateContext('Female', '(aged %s)', $age);
+ break;
+ default:
+ /* I18N: The age of an individual at a given date */
+ $ageText = I18N::translate('(aged %s)', $age);
+ break;
+ }
+ }
+ }
+ }
+
+ if ($tag !== 'DEAT' && $death_date->isOK() && Date::compare($death_date, $date) <= 0) {
+ $death_day = $death_date->minimumDate()->day();
+ $event_day = $date->minimumDate()->day();
+ if ($death_day !== 0 && $event_day !== 0 && Date::compare($death_date, $date) === 0) {
+ // On the exact date of death?
+ // NOTE: this path is never reached. Keep the code (translation) in case
+ // we decide to re-introduce it.
+ $ageText = I18N::translate('(on the date of death)');
+ } else {
+ // After death
+ $age = (string) new Age($death_date, $date);
+ $ageText = I18N::translate('(%s after death)', $age);
+ }
+
+ // Family events which occur after death are probably errors
+ if ($fact->record() instanceof Family) {
+ $ageText .= view('icons/warning');
+ }
+ }
+
+ if ($ageText !== '') {
+ $html .= ' <span class="age">' . $ageText . '</span>';
+ }
+ }
+ }
+}
+// print gedcom ages
+$age_labels = [
+ I18N::translate('Age') => $fact_age,
+ I18N::translate('Husband') => $husb_age,
+ I18N::translate('Wife') => $wife_age,
+];
+
+foreach (array_filter($age_labels) as $label => $age) {
+ $html .= ' <span class="label">' . $label . ':</span> <span class="age">' . $age . '</span>';
+}
+
+?>
+<div class="wt-fact-date-age">
+ <?= $html ?>
+</div>
diff --git a/resources/views/fact-edit-links.phtml b/resources/views/fact-edit-links.phtml
new file mode 100644
index 0000000000..e6dcda986c
--- /dev/null
+++ b/resources/views/fact-edit-links.phtml
@@ -0,0 +1,17 @@
+<?php
+
+use Fisharebest\Webtrees\Fact;
+
+/**
+ * @var Fact $fact
+ * @var string|null $url
+ */
+
+?>
+<?php if ($fact->canEdit()) : ?>
+ <div class="pt-2 wt-fact-edit-links">
+ <?= view('edit/icon-fact-edit', ['fact' => $fact, 'url' => $url ?? null]) ?>
+ <?= view('edit/icon-fact-copy', ['fact' => $fact]) ?>
+ <?= view('edit/icon-fact-delete', ['fact' => $fact]) ?>
+ </div>
+<?php endif ?>
diff --git a/resources/views/fact-gedcom-fields.phtml b/resources/views/fact-gedcom-fields.phtml
new file mode 100644
index 0000000000..a050137a16
--- /dev/null
+++ b/resources/views/fact-gedcom-fields.phtml
@@ -0,0 +1,67 @@
+<?php
+
+use Fisharebest\Webtrees\Elements\XrefSource;
+use Fisharebest\Webtrees\Gedcom;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Source;
+use Fisharebest\Webtrees\Tree;
+use Ramsey\Uuid\Uuid;
+
+/**
+ * @var string $gedcom
+ * @var string $parent e.g. "INDI:BIRT:DATE"
+ * @var Tree $tree
+ */
+
+$hierarchy = explode(':', $parent);
+
+// Merge CONT records onto their parent line.
+$gedcom = preg_replace('/\n\d CONT ?/', "\r", $gedcom);
+
+preg_match_all('/^(\d+) (\w+) ?(.*)/m', $gedcom, $matches);
+[, $levels, $tags, $values] = $matches;
+$levels = array_map(static fn (string $x): int => (int) $x, $levels);
+$keys = array_keys($levels);
+$elements = [];
+
+foreach ($keys as $key) {
+ $hierarchy[$levels[$key]] = $tags[$key];
+ $full_tag = implode(':', array_slice($hierarchy, 0, 1 + $levels[$key]));
+ $elements[$key] = Registry::elementFactory()->make($full_tag);
+}
+
+/** @todo filter links to private records and their subtags */
+
+?>
+
+<?php if ($elements[0] instanceof XrefSource && preg_match('/^@(' . Gedcom::REGEX_XREF . ')@$/', $values[0], $match) === 1) : ?>
+ <?php $source = Registry::sourceFactory()->make($match[1], $tree) ?>
+ <?php if ($source instanceof Source) : ?>
+ <?php $id = 'collapse-' . Uuid::uuid4()->toString() ?>
+ <?php $expanded = $tree->getPreference('EXPAND_SOURCES') === '1' ?>
+ <div class="fact_SOUR">
+ <a href="#<?= e($id) ?>" role="button" data-bs-toggle="collapse" aria-controls="<?= e($id) ?>" aria-expanded="<?= $expanded ? 'true' : 'false' ?>">
+ <?= view('icons/expand') ?>
+ <?= view('icons/collapse') ?>
+ </a>
+
+ <?= I18N::translate('<span class="label">%1$s:</span> <span class="field" dir="auto">%2$s</span>', I18N::translate('Source'), '<a href="' . e($source->url()) . '">' . $source->fullName() . '</a>') ?>
+ </div>
+
+ <div id="<?= e($id) ?>" class="ps-4 collapse <?= $expanded ? 'show' : '' ?>">
+ <?php array_shift($keys) ?>
+ <?php foreach ($keys as $key) : ?>
+ <?php if ($values[$key] !== '') : ?>
+ <?= $elements[$key]->labelValue(strtr($values[$key], ["\r" => "\n"]), $tree) ?>
+ <?php endif ?>
+ <?php endforeach ?>
+ </div>
+ <?php endif ?>
+<?php else : ?>
+ <?php foreach ($keys as $key) : ?>
+ <?php if ($values[$key] !== '') : ?>
+ <?= $elements[$key]->labelValue(strtr($values[$key], ["\r" => "\n"]), $tree) ?>
+ <?php endif ?>
+ <?php endforeach ?>
+<?php endif ?>
diff --git a/resources/views/fact-media.phtml b/resources/views/fact-media.phtml
new file mode 100644
index 0000000000..78095a3564
--- /dev/null
+++ b/resources/views/fact-media.phtml
@@ -0,0 +1,17 @@
+<?php
+
+use Fisharebest\Webtrees\Fact;
+
+/**
+ * @var Fact $fact
+ */
+
+?>
+
+<?php if (preg_match_all('/\n(2 OBJE\b.*(?:\n[^2].*)*)/', $fact->gedcom(), $matches, PREG_SET_ORDER) > 0) : ?>
+ <div class="wt-fact-media mt-2">
+ <?php foreach ($matches as $match) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $match[1], 'parent' => $fact->tag(), 'tree' => $fact->record()->tree()]) ?>
+ <?php endforeach ?>
+ </div>
+<?php endif ?>
diff --git a/resources/views/fact-notes.phtml b/resources/views/fact-notes.phtml
new file mode 100644
index 0000000000..bb7d587797
--- /dev/null
+++ b/resources/views/fact-notes.phtml
@@ -0,0 +1,17 @@
+<?php
+
+use Fisharebest\Webtrees\Fact;
+
+/**
+ * @var Fact $fact
+ */
+
+?>
+
+<?php if (preg_match_all('/\n(2 NOTE\b.*(?:\n[^2].*)*)/', $fact->gedcom(), $matches, PREG_SET_ORDER) > 0) : ?>
+ <div class="wt-fact-notes mt-2">
+ <?php foreach ($matches as $match) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $match[1], 'parent' => $fact->tag(), 'tree' => $fact->record()->tree()]) ?>
+ <?php endforeach ?>
+ </div>
+<?php endif ?>
diff --git a/resources/views/fact-parent-age.phtml b/resources/views/fact-parent-age.phtml
new file mode 100644
index 0000000000..59e6bc41f4
--- /dev/null
+++ b/resources/views/fact-parent-age.phtml
@@ -0,0 +1,44 @@
+<?php
+
+use Fisharebest\Webtrees\Age;
+use Fisharebest\Webtrees\I18N;
+
+/**
+ * @var Age $age
+ * @var bool $died
+ * @var string $sex
+ */
+
+?>
+
+<?php if ($sex === 'F') : ?>
+ <?php if ($died) : ?>
+ <span title="<?= I18N::translate('Death of a mother') ?>" class="parentdeath">
+ <small><?= view('icons/sex', ['sex' => $sex]) ?></small><?= I18N::number($age->ageYears()) ?>
+ </span>
+ <?php else : ?>
+ <span title="<?= I18N::translate('Mother’s age') ?>">
+ <small><?= view('icons/sex', ['sex' => $sex]) ?></small><?= I18N::number($age->ageYears()) ?>
+ </span>
+ <?php endif ?>
+<?php elseif ($sex === 'M') : ?>
+ <?php if ($died) : ?>
+ <span title="<?= I18N::translate('Death of a father') ?>" class="parentdeath">
+ <small><?= view('icons/sex', ['sex' => $sex]) ?></small><?= I18N::number($age->ageYears()) ?>
+ </span>
+ <?php else : ?>
+ <span title="<?= I18N::translate('Father’s age') ?>">
+ <small><?= view('icons/sex', ['sex' => $sex]) ?></small><?= I18N::number($age->ageYears()) ?>
+ </span>
+ <?php endif ?>
+<?php else : ?>
+ <?php if ($died) : ?>
+ <span title="<?= I18N::translate('Death of a parent') ?>" class="parentdeath">
+ <small><?= view('icons/sex', ['sex' => $sex]) ?></small><?= I18N::number($age->ageYears()) ?>
+ </span>
+ <?php else : ?>
+ <span title="<?= I18N::translate('Parent’s age') ?>">
+ <small><?= view('icons/sex', ['sex' => $sex]) ?></small><?= I18N::number($age->ageYears()) ?>
+ </span>
+ <?php endif ?>
+<?php endif ?>
diff --git a/resources/views/fact-parents-age.phtml b/resources/views/fact-parents-age.phtml
new file mode 100644
index 0000000000..d8f0a1b77f
--- /dev/null
+++ b/resources/views/fact-parents-age.phtml
@@ -0,0 +1,29 @@
+<?php
+
+use Fisharebest\Webtrees\Age;
+use Fisharebest\Webtrees\Date;
+use Fisharebest\Webtrees\Family;
+use Fisharebest\Webtrees\Individual;
+
+/**
+ * @var Individual $individual
+ * @var Date $birth_date
+ */
+
+$family = $individual->childFamilies()->first();
+
+?>
+
+<?php if ($family instanceof Family && $birth_date->isOK()) : ?>
+ <span class="age">
+ <?php foreach ($family->spouses() as $parent) : ?>
+ <?php if ($parent->getBirthDate()->isOK()) : ?>
+ <?php if ($parent->sex() === 'F') : ?>
+ <?= view('fact-parent-age', ['age' => new Age($parent->getBirthDate(), $birth_date), 'died' => $parent->getDeathDate()->isOK() && $parent->getDeathDate()->maximumJulianDay() < $birth_date->minimumJulianDay() + 90, 'sex' => $parent->sex()]) ?>
+ <?php else : ?>
+ <?= view('fact-parent-age', ['age' => new Age($parent->getBirthDate(), $birth_date), 'died' => $parent->getDeathDate()->isOK() && $parent->getDeathDate()->maximumJulianDay() < $birth_date->minimumJulianDay(), 'sex' => $parent->sex()]) ?>
+ <?php endif ?>
+ <?php endif ?>
+ <?php endforeach ?>
+ </span>
+<?php endif ?>
diff --git a/resources/views/fact-place.phtml b/resources/views/fact-place.phtml
new file mode 100644
index 0000000000..fcea112478
--- /dev/null
+++ b/resources/views/fact-place.phtml
@@ -0,0 +1,57 @@
+<?php
+
+use Fisharebest\Webtrees\Date;
+use Fisharebest\Webtrees\Fact;
+use Fisharebest\Webtrees\GedcomRecord;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Module\ModuleMapLinkInterface;
+use Fisharebest\Webtrees\Place;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\ModuleService;
+
+/**
+ * @var bool $cal_link
+ * @var Fact $fact
+ * @var GedcomRecord $record
+ * @var bool $time
+ */
+
+?>
+<div class="wt-fact-place">
+ <?php if (preg_match('/\n(2 PLAC.*(?:\n[3-9].*)*)/', $fact->gedcom(), $match) === 1) : ?>
+ <?php $placerec = $match[1]; ?>
+ <?= $fact->place()->fullName($fact->id() !== 'histo') ?>
+
+ <?php if (preg_match_all('/\n3 (?:_HEB|ROMN|FONE) (.+)/', $placerec, $matches)) : ?>
+ <?php foreach ($matches[1] as $match) : ?>
+ — <?= (new Place($match, $record->tree()))->fullName() ?>
+ <?php endforeach ?>
+ <?php endif ?>
+
+ <?php if ($fact->latitude() !== null && $fact->longitude() !== null) : ?>
+ <div class="wt-fact-coordinates">
+ <span class="label"><?= I18N::translate('Latitude') ?>: </span><?= $fact->latitude() ?>
+ <span class="label"><?= I18N::translate('Longitude') ?>: </span><?= $fact->longitude()?>
+ <?= app(ModuleService::class)->findByInterface(ModuleMapLinkInterface::class)->map(fn(ModuleMapLinkInterface $module): string => ' ' . $module->mapLink($fact))->implode('') ?>
+ </div>
+ <?php endif ?>
+
+ <?php if (preg_match_all('/\n(3 NOTE\b.*(?:\n[^3].*)*)/', $placerec, $matches, PREG_SET_ORDER) > 0) : ?>
+ <?php foreach ($matches as $match) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $match[1], 'parent' => $fact->tag() . ':PLAC:NOTE', 'tree' => $record->tree()]) ?>
+ <?php endforeach ?>
+ <?php endif ?>
+ <?php endif ?>
+
+ <?php if (preg_match('/2 TEMP (.+)/', $fact->gedcom(), $match)) : ?>
+ <?= Registry::elementFactory()->make($fact->tag() . ':TEMP')->labelValue($match[1], $record->tree()) ?>
+ <?php endif ?>
+
+ <?php if (preg_match('/2 STAT (.+)/', $fact->gedcom(), $match)) : ?>
+ <?= Registry::elementFactory()->make($fact->tag() . ':STAT')->labelValue($match[1], $record->tree()) ?>
+
+ <?php if (preg_match('/3 DATE (.+)/', $fact->gedcom(), $match)) : ?>
+ <?= Registry::elementFactory()->make($fact->tag() . ':STAT:DATE')->labelValue((new Date($match[1]))->display(), $record->tree()) ?>
+ <?php endif ?>
+ <?php endif ?>
+</div>
diff --git a/resources/views/fact-sources.phtml b/resources/views/fact-sources.phtml
new file mode 100644
index 0000000000..3d2abb0b12
--- /dev/null
+++ b/resources/views/fact-sources.phtml
@@ -0,0 +1,17 @@
+<?php
+
+use Fisharebest\Webtrees\Fact;
+
+/**
+ * @var Fact $fact
+ */
+
+?>
+
+<?php if (preg_match_all('/\n(2 SOUR\b.*(?:\n[^2].*)*)/', $fact->gedcom(), $matches, PREG_SET_ORDER) > 0) : ?>
+ <div class="wt-fact-sources mt-2">
+ <?php foreach ($matches as $match) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $match[1], 'parent' => $fact->tag(), 'tree' => $fact->record()->tree()]) ?>
+ <?php endforeach ?>
+ </div>
+<?php endif ?>
diff --git a/resources/views/fact.phtml b/resources/views/fact.phtml
new file mode 100644
index 0000000000..1ab0405694
--- /dev/null
+++ b/resources/views/fact.phtml
@@ -0,0 +1,158 @@
+<?php
+
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\Elements\UnknownElement;
+use Fisharebest\Webtrees\Elements\XrefAssociate;
+use Fisharebest\Webtrees\Fact;
+use Fisharebest\Webtrees\Family;
+use Fisharebest\Webtrees\Gedcom;
+use Fisharebest\Webtrees\GedcomRecord;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Individual;
+use Fisharebest\Webtrees\Media;
+use Fisharebest\Webtrees\Module\ModuleChartInterface;
+use Fisharebest\Webtrees\Module\ModuleInterface;
+use Fisharebest\Webtrees\Module\RelationshipsChartModule;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\ModuleService;
+use Fisharebest\Webtrees\Services\RelationshipService;
+
+/**
+ * @var Fact $fact
+ * @var GedcomRecord $record
+ */
+
+$parent = $fact->record();
+$tree = $parent->tree();
+[, $tag] = explode(':', $fact->tag());
+$label = $fact->label();
+$value = $fact->value();
+$type = $fact->attribute('TYPE');
+$id = $fact->id();
+
+$element = Registry::elementFactory()->make($fact->tag());
+
+// New or deleted facts need different styling
+$styles = [];
+if ($fact->isPendingAddition()) {
+ $styles[] = 'wt-new';
+}
+if ($fact->isPendingDeletion()) {
+ $styles[] = 'wt-old';
+}
+
+// Event of close relative
+if ($tag === 'EVEN' && $value === 'CLOSE_RELATIVE') {
+ $value = '';
+ $styles[] = 'wt-relation-fact collapse';
+}
+
+// Event of close associates
+if ($id === 'asso') {
+ $styles[] = 'wt-associate-fact collapse';
+}
+
+if ($element instanceof UnknownElement && $tree->getPreference('HIDE_GEDCOM_ERRORS') === '0') {
+ $styles[] = 'd-none';
+}
+
+
+// historical facts
+if ($id === 'histo') {
+ $styles[] = 'wt-historic-fact collapse';
+}
+
+// Use marriage type as the label. e.g. "Civil partnership"
+if ($tag === 'MARR') {
+ $label = $fact->label();
+ $type = '';
+}
+
+?>
+<tr class="<?= implode(' ', $styles) ?>">
+ <th scope="row">
+ <div class="wt-fact-label"><?= $label?></div>
+
+ <?php if ($id !== 'histo' && $id !== 'asso' && $fact->canEdit() && !in_array($tag, ['HUSB', 'WIFE', 'CHIL', 'FAMC', 'FAMS'], true)) : ?>
+ <?= view('fact-edit-links', ['fact' => $fact, 'url' => $record->url()]) ?>
+ <?php endif ?>
+
+ <?php if ($tree->getPreference('SHOW_FACT_ICONS')) : ?>
+ <span class="wt-fact-icon wt-fact-icon-<?= e($tag) ?>" title="<?= strip_tags($label) ?>"></span>
+ <?php endif ?>
+ </th>
+
+ <td>
+ <?php if ($fact->target() instanceof Media) : ?>
+ <div class="d-flex">
+ <?php foreach ($fact->target()->mediaFiles() as $media_file) : ?>
+ <?= $media_file->displayImage(100, 100, 'contain', []) ?>
+ <?php endforeach ?>
+ </div>
+
+ <a href="<?= e($fact->target()->url()) ?>"><?= $fact->target()->fullName() ?></a>
+
+ <?php foreach ($fact->target()->facts(['NOTE']) as $note) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $note->gedcom(), 'parent' => $fact->target()->tag(), 'tree' => $fact->record()->tree()]) ?>
+ <?php endforeach ?>
+ <?php else : ?>
+ <div class="wt-fact-main-attributes">
+ <?php if ($parent !== $record) : ?>
+ <div class="wt-fact-record">
+ <?php if ($parent instanceof Family) : ?>
+ <?php foreach ($parent->spouses()->filter(static fn($individual): bool => $individual !== $record) as $spouse) : ?>
+ <a href="<?= e($spouse->url()) ?>"><?= $spouse->fullName() ?></a> —
+ <?php endforeach ?>
+ <a href="<?= e($parent->url()) ?>"><?= I18N::translate('View this family') ?></a>
+ <?php elseif ($parent instanceof Individual) : ?>
+ <a href="<?= e($parent->url()) ?>"><?= $parent->fullName() ?></a>
+ <?php endif ?>
+ </div>
+ <?php endif ?>
+
+ <div class="wt-fact-value">
+ <?= $element->value($value, $tree) ?>
+ <?php if ($element instanceof XrefAssociate && $fact->target() instanceof Individual) : ?>
+ <?php
+ $module = app(ModuleService::class)->findByComponent(ModuleChartInterface::class, $tree, Auth::user())
+ ->first(static fn (ModuleInterface $module):bool => $module instanceof RelationshipsChartModule)
+ ?>
+
+ <?php if ($module instanceof RelationshipsChartModule) : ?>
+ — <a href="<?= $module->chartUrl($fact->target(), ['xref2' => $record->xref()]) ?>" rel="nofollow">
+ <?= app(RelationshipService::class)->getCloseRelationshipName($fact->target(), $record) ?>
+ </a>
+ <?php endif ?>
+ <?php endif ?>
+ </div>
+
+ <!-- Type of this fact/event (allow user-translations) -->
+ <?php if ($type !== '' && $tag !== 'EVEN' && $tag !== 'FACT') : ?>
+ <div class="wt-fact-type">
+ <?= Registry::elementFactory()->make($fact->tag() . ':TYPE')->labelValue(I18N::translate($type), $tree) ?>
+ </div>
+ <?php endif ?>
+
+ <?= view('fact-date', ['cal_link' => 'true', 'fact' => $fact, 'record' => $record, 'time' => true]) ?>
+ <?= view('fact-place', ['fact' => $fact, 'record' => $record]) ?>
+ </div>
+
+ <div class="wt-fact-other-attributes mt-2">
+ <?php preg_match_all('/\n2 (' . Gedcom::REGEX_TAG . ') ?((\n[3-9].*)*)/', $fact->gedcom(), $matches, PREG_SET_ORDER) ?>
+ <?php foreach ($matches as $match) : ?>
+ <?php if (!in_array($match[1], ['DATE', 'TIME', 'AGE', 'HUSB', 'WIFE', 'PLAC', 'ASSO', '_ASSO', 'STAT', 'TEMP', 'TYPE', 'CONT', 'NOTE', 'OBJE', 'SOUR'], true)) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $match[0], 'parent' => $fact->tag() . ':' . $match[1], 'tree' => $tree]) ?>
+ <?php endif ?>
+ <?php endforeach; ?>
+ </div>
+
+ <?php if ($id !== 'asso') : ?>
+ <?= view('fact-associates', ['fact' => $fact]) ?>
+ <?php endif ?>
+
+ <?= view('fact-sources', ['fact' => $fact]) ?>
+ <?= view('fact-notes', ['fact' => $fact]) ?>
+ <?= view('fact-media', ['fact' => $fact]) ?>
+ <?php endif ?>
+ </td>
+</tr>
diff --git a/resources/views/family-page.phtml b/resources/views/family-page.phtml
index 061566ed5b..b2b18df9ec 100644
--- a/resources/views/family-page.phtml
+++ b/resources/views/family-page.phtml
@@ -1,10 +1,7 @@
<?php
-use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Fact;
use Fisharebest\Webtrees\Family;
-use Fisharebest\Webtrees\Functions\FunctionsPrint;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\I18N;
use Illuminate\Support\Collection;
@@ -44,12 +41,12 @@ use Illuminate\Support\Collection;
</tr>
<?php else : ?>
<?php foreach ($facts as $fact) : ?>
- <?php FunctionsPrintFacts::printFact($fact, $record) ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $record]) ?>
<?php endforeach ?>
<?php endif ?>
- <?php if (Auth::isEditor($record->tree())) : ?>
- <?php FunctionsPrint::printAddNewFact($record) ?>
+ <?php if ($record->canEdit()) : ?>
+ <?= view('fact-add-new', ['record' => $record]) ?>
<?php endif ?>
</table>
</div>
diff --git a/resources/views/individual-name.phtml b/resources/views/individual-name.phtml
index f744477f0e..4245ddcd74 100644
--- a/resources/views/individual-name.phtml
+++ b/resources/views/individual-name.phtml
@@ -2,8 +2,6 @@
use Fisharebest\Webtrees\Fact;
use Fisharebest\Webtrees\Registry;
-use Fisharebest\Webtrees\Functions\FunctionsPrint;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\Http\RequestHandlers\CopyFact;
use Fisharebest\Webtrees\Http\RequestHandlers\DeleteFact;
use Fisharebest\Webtrees\Http\RequestHandlers\EditFactPage;
@@ -69,9 +67,9 @@ if ($fact->isPendingDeletion()) {
<?php endforeach ?>
</dl>
- <?= FunctionsPrintFacts::printFactSources($tree, $fact->gedcom(), 2) ?>
- <?= FunctionsPrint::printFactNotes($tree, $fact->gedcom(), 2) ?>
-
+ <?= view('fact-sources', ['fact' => $fact]) ?>
+ <?= view('fact-notes', ['fact' => $fact]) ?>
+
<?php if ($fact->canEdit()) : ?>
<div class="d-flex">
<a class="btn btn-link ms-auto" href="<?= e(route(EditFactPage::class, ['xref' => $individual->xref(), 'fact_id' => $fact->id(), 'tree' => $individual->tree()->name()])) ?>" title="<?= I18N::translate('Edit the name') ?>">
diff --git a/resources/views/individual-sex.phtml b/resources/views/individual-sex.phtml
index b47f1fe249..8e45994f09 100644
--- a/resources/views/individual-sex.phtml
+++ b/resources/views/individual-sex.phtml
@@ -1,8 +1,6 @@
<?php
use Fisharebest\Webtrees\Fact;
-use Fisharebest\Webtrees\Functions\FunctionsPrint;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\Http\RequestHandlers\EditFactPage;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Registry;
@@ -33,9 +31,9 @@ if ($fact->isPendingDeletion()) {
</div>
<div id="name-content-<?= $fact->id() ?>" class="accordion-collapse collapse" data-bs-parent="#individual-names" aria-labelledby="name-header-<?= $fact->id() ?>">
<div class="accordion-body">
- <?= FunctionsPrintFacts::printFactSources($tree, $fact->gedcom(), 2) ?>
- <?= FunctionsPrint::printFactNotes($tree, $fact->gedcom(), 2) ?>
-
+ <?= view('fact-sources', ['fact' => $fact]) ?>
+ <?= view('fact-notes', ['fact' => $fact]) ?>
+
<?php if ($fact->canEdit()) : ?>
<div class="d-flex">
<a class="btn btn-link ms-auto" href="<?= e(route(EditFactPage::class, ['xref' => $fact->record()->xref(), 'fact_id' => $fact->id(), 'tree' => $fact->record()->tree()->name()])) ?>"
diff --git a/resources/views/media-page-details.phtml b/resources/views/media-page-details.phtml
index e6295aa455..b3de24531a 100644
--- a/resources/views/media-page-details.phtml
+++ b/resources/views/media-page-details.phtml
@@ -2,7 +2,6 @@
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Fact;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\Http\RequestHandlers\DeleteFact;
use Fisharebest\Webtrees\Http\RequestHandlers\EditMediaFileModal;
use Fisharebest\Webtrees\I18N;
@@ -27,7 +26,7 @@ use League\Flysystem\FilesystemOperator;
<th scope="row">
<?= I18N::translate('Media file') ?>
<?php if ($record->canEdit()) : ?>
- <div class="editfacts nowrap">
+ <div class="pt-2 wt-fact-edit-links">
<a class="btn btn-link" href="#" data-bs-toggle="modal" data-bs-backdrop="static" data-bs-target="#wt-ajax-modal" data-wt-href="<?= route(EditMediaFileModal::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref(), 'fact_id' => $media_file->factId()]) ?>" title="<?= I18N::translate('Edit') ?>">
<?= view('icons/edit') ?>
<span class="visually-hidden">
@@ -91,6 +90,6 @@ use League\Flysystem\FilesystemOperator;
<?php endforeach ?>
<?php foreach ($record->facts()->filter(fn (Fact $fact): bool => $fact->tag() !== 'OBJE:FILE') as $fact) : ?>
- <?php FunctionsPrintFacts::printFact($fact, $record) ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $record]) ?>
<?php endforeach ?>
</table>
diff --git a/resources/views/modules/media-list/page.phtml b/resources/views/modules/media-list/page.phtml
index a034eee28e..522082f12a 100644
--- a/resources/views/modules/media-list/page.phtml
+++ b/resources/views/modules/media-list/page.phtml
@@ -1,8 +1,6 @@
<?php
use Fisharebest\Webtrees\Auth;
-use Fisharebest\Webtrees\Functions\FunctionsPrint;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Media;
use Fisharebest\Webtrees\MediaFile;
@@ -121,8 +119,15 @@ use League\Flysystem\FilesystemOperator;
$element = Registry::elementFactory()->make('OBJE:FILE:FORM:TYPE');
echo $element->labelValue($media_file->type(), $media_object->tree());
}
- echo FunctionsPrintFacts::printFactSources($tree, $media_object->gedcom(), 1);
- echo FunctionsPrint::printFactNotes($tree, $media_object->gedcom(), 1);
+
+ foreach ($media_object->facts(['SOUR']) as $fact) {
+ echo view('fact-gedcom-fields', ['gedcom' => $fact->gedcom(), 'parent' => $media_object->tag(), 'tree' => $tree]);
+ }
+
+ foreach ($media_object->facts(['NOTE']) as $fact) {
+ echo view('fact-gedcom-fields', ['gedcom' => $fact->gedcom(), 'parent' => $media_object->tag(), 'tree' => $tree]);
+ }
+
if ($media_file->isExternal()) {
echo Registry::elementFactory()->make('OBJE:FILE')->labelValue($media_file->filename(), $media_object->tree());
} elseif ($media_file->fileExists($data_filesystem)) {
diff --git a/resources/views/modules/media/tab.phtml b/resources/views/modules/media/tab.phtml
index 5482791b12..479c51d78d 100644
--- a/resources/views/modules/media/tab.phtml
+++ b/resources/views/modules/media/tab.phtml
@@ -1,7 +1,6 @@
<?php
use Fisharebest\Webtrees\Fact;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Illuminate\Support\Collection;
@@ -16,11 +15,44 @@ use Illuminate\Support\Collection;
?>
<div class="wt-tab-media py-4">
<table class="table wt-facts-table">
+ <tr>
+ <td colspan="2">
+ <label>
+ <input id="show-level-2-media" type="checkbox" data-bs-toggle="collapse" data-bs-target=".wt-level-two-media" data-wt-persist="level-two-media">
+ <?= I18N::translate('Show all media') ?>
+ </label>
+ </td>
+ </tr>
+
<?php foreach ($facts as $fact) : ?>
- <?php FunctionsPrintFacts::printMainMedia($fact, 1) ?>
- <?php FunctionsPrintFacts::printMainMedia($fact, 2) ?>
- <?php FunctionsPrintFacts::printMainMedia($fact, 3) ?>
- <?php FunctionsPrintFacts::printMainMedia($fact, 4) ?>
+ <?php if (str_ends_with($fact->tag(), ':OBJE')) : ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $individual]) ?>
+ <?php else : ?>
+ <?php
+ if ($fact->isPendingAddition()) {
+ $styleadd = 'wt-new ';
+ } elseif ($fact->isPendingDeletion()) {
+ $styleadd = 'wt-old ';
+ } else {
+ $styleadd = '';
+ }
+ ?>
+
+ <tr class="wt-level-two-media collapse">
+ <th scope="row" class="rela <?= $styleadd ?>">
+ <?= $fact->label() ?>
+ <?= view('fact-edit-links', ['fact' => $fact, 'url' => $fact->record()->url() . '#tab-media']) ?>
+ </th>
+
+ <td class="<?= $styleadd ?>">
+ <?php if (preg_match_all('/\n([2-4] OBJE .*)/', $fact->gedcom(), $matches, PREG_SET_ORDER) > 0) : ?>
+ <?php foreach($matches as $match) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $match[1], 'parent' => $fact->tag(), 'tree' => $fact->record()->tree()]) ?>
+ <?php endforeach ?>
+ <?php endif ?>
+ </td>
+ </tr>
+ <?php endif ?>
<?php endforeach ?>
<?php if ($facts->isEmpty()) : ?>
diff --git a/resources/views/modules/notes/tab.phtml b/resources/views/modules/notes/tab.phtml
index 9dde4dc81e..22d559f6d5 100644
--- a/resources/views/modules/notes/tab.phtml
+++ b/resources/views/modules/notes/tab.phtml
@@ -1,10 +1,13 @@
<?php
+use Fisharebest\Webtrees\Elements\SubmitterText;
use Fisharebest\Webtrees\Fact;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
+use Fisharebest\Webtrees\Gedcom;
use Fisharebest\Webtrees\Http\RequestHandlers\AddNewFact;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
+use Fisharebest\Webtrees\Note;
+use Fisharebest\Webtrees\Registry;
use Illuminate\Support\Collection;
/**
@@ -28,11 +31,52 @@ use Illuminate\Support\Collection;
</tr>
<?php foreach ($facts as $fact) : ?>
- <?php FunctionsPrintFacts::printMainNotes($fact, 1) ?>
- <?php FunctionsPrintFacts::printMainNotes($fact, 2) ?>
- <?php FunctionsPrintFacts::printMainNotes($fact, 3) ?>
- <?php FunctionsPrintFacts::printMainNotes($fact, 4) ?>
- <?php endforeach ?>
+ <?php if ($fact->tag() === 'INDI:NOTE' || $fact->tag() === 'FAM:NOTE') : ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $individual]) ?>
+ <?php else : ?>
+ <?php
+ if ($fact->isPendingAddition()) {
+ $styleadd = 'wt-new ';
+ } elseif ($fact->isPendingDeletion()) {
+ $styleadd = 'wt-old ';
+ } else {
+ $styleadd = '';
+ }
+ ?>
+
+ <tr class="wt-level-two-note collapse">
+ <th scope="row" class="rela <?= $styleadd ?>">
+ <?= $fact->label() ?>
+ <?= view('fact-edit-links', ['fact' => $fact, 'url' => $fact->record()->url() . '#tab-notes']) ?>
+ </th>
+
+ <td class="<?= $styleadd ?>">
+ <?php preg_match_all("/\n[1-9] NOTE ?(.*(?:\n\d CONT.*)*)/", $fact->gedcom(), $matches, PREG_SET_ORDER) ?>
+ <?php foreach ($matches as $match) : ?>
+ <div class="mb-2">
+ <?php $text = preg_replace('/\n\d CONT ?/', "\n", $match[1]) ?>
+ <?php if (preg_match('/^@' . Gedcom::REGEX_XREF . '@$/', $text)) : ?>
+ <?php $note = Registry::noteFactory()->make(trim($text, '@'), $individual->tree()) ?>
+ <?php if ($note instanceof Note) : ?>
+ <?php if ($note->canShow()) : ?>
+ <a href="<?= e($note->url()) ?>">
+ <?= I18N::translate('Shared note') ?>
+ <?= view('icons/note') ?>
+ </a>
+ <?= (new SubmitterText(''))->value($note->getNote(), $individual->tree()) ?>
+ <?php endif ?>
+ <?php else : ?>
+ <span class="error"><?= e($text) ?></span>
+ <?php endif ?>
+ <?php else : ?>
+ <?= (new SubmitterText(''))->value($text, $individual->tree()) ?>
+ <?php endif ?>
+ </div>
+ <?php endforeach ?>
+ <?php endif ?>
+ <?php endforeach ?>
+ </td>
+ </tr>
<?php if ($facts->isEmpty()) : ?>
<tr>
diff --git a/resources/views/modules/personal_facts/tab.phtml b/resources/views/modules/personal_facts/tab.phtml
index 8e428b5e0e..8768028d1f 100644
--- a/resources/views/modules/personal_facts/tab.phtml
+++ b/resources/views/modules/personal_facts/tab.phtml
@@ -1,8 +1,6 @@
<?php
use Fisharebest\Webtrees\Fact;
-use Fisharebest\Webtrees\Functions\FunctionsPrint;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Illuminate\Support\Collection;
@@ -52,7 +50,7 @@ use Illuminate\Support\Collection;
</tr>
<?php foreach ($facts as $fact) : ?>
- <?php FunctionsPrintFacts::printFact($fact, $individual) ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $individual]) ?>
<?php endforeach ?>
<?php if ($facts->isEmpty()) : ?>
@@ -64,7 +62,7 @@ use Illuminate\Support\Collection;
<?php endif ?>
<?php if ($individual->canEdit()) : ?>
- <?php FunctionsPrint::printAddNewFact($individual) ?>
+ <?= view('fact-add-new', ['record' => $individual]) ?>
<?php endif ?>
</tbody>
</table>
diff --git a/resources/views/modules/random_media/slide-show.phtml b/resources/views/modules/random_media/slide-show.phtml
index 5aa33721b3..54b531c88d 100644
--- a/resources/views/modules/random_media/slide-show.phtml
+++ b/resources/views/modules/random_media/slide-show.phtml
@@ -1,6 +1,5 @@
<?php
-use Fisharebest\Webtrees\Functions\FunctionsPrint;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Media;
use Fisharebest\Webtrees\MediaFile;
@@ -46,7 +45,9 @@ use Fisharebest\Webtrees\Tree;
</figure>
<p class="wt-slide-show-notes text-center">
- <?= FunctionsPrint::printFactNotes($tree, $media->gedcom(), 1) ?>
+ <?php foreach ($media->facts(['NOTE']) as $fact) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $fact->gedcom(), 'parent' => $media->tag(), 'tree' => $tree]) ?>
+ <?php endforeach ?>
</p>
<ul class="fa-ul wt-slide-show-links">
diff --git a/resources/views/modules/sources_tab/tab.phtml b/resources/views/modules/sources_tab/tab.phtml
index 3396aaa758..99604f8eb9 100644
--- a/resources/views/modules/sources_tab/tab.phtml
+++ b/resources/views/modules/sources_tab/tab.phtml
@@ -1,7 +1,6 @@
<?php
use Fisharebest\Webtrees\Fact;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\Http\RequestHandlers\AddNewFact;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
@@ -28,15 +27,41 @@ use Illuminate\Support\Collection;
</tr>
<?php foreach ($facts as $fact) : ?>
- <?php FunctionsPrintFacts::printMainSources($fact, 1) ?>
- <?php FunctionsPrintFacts::printMainSources($fact, 2) ?>
+ <?php if (str_ends_with($fact->tag(), ':SOUR')) : ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $individual]) ?>
+ <?php else : ?>
+ <?php
+ if ($fact->isPendingAddition()) {
+ $styleadd = 'wt-new ';
+ } elseif ($fact->isPendingDeletion()) {
+ $styleadd = 'wt-old ';
+ } else {
+ $styleadd = '';
+ }
+ ?>
+
+ <tr class="wt-level-two-source collapse">
+ <th scope="row" class="rela <?= $styleadd ?>">
+ <?= $fact->label() ?>
+ <?= view('fact-edit-links', ['fact' => $fact, 'url' => $fact->record()->url() . '#tab-sources']) ?>
+ </th>
+
+ <td class="<?= $styleadd ?>">
+ <?php if (preg_match_all('/\n(2 SOUR\b.*(?:\n[^2].*)*)/', $fact->gedcom(), $matches, PREG_SET_ORDER) > 0) : ?>
+ <?php foreach($matches as $match) : ?>
+ <?= view('fact-gedcom-fields', ['gedcom' => $match[1], 'parent' => $fact->tag(), 'tree' => $fact->record()->tree()]) ?>
+ <?php endforeach ?>
+ <?php endif ?>
+ </td>
+ </tr>
+ <?php endif ?>
<?php endforeach ?>
<?php if ($facts->isEmpty()) : ?>
<tr>
<td colspan="2">
<?= I18N::translate('There are no source citations for this individual.') ?>
- </td>
+ </td>
</tr>
<?php endif ?>
diff --git a/resources/views/modules/timeline-chart/chart.phtml b/resources/views/modules/timeline-chart/chart.phtml
index d88425941f..e025fafde8 100644
--- a/resources/views/modules/timeline-chart/chart.phtml
+++ b/resources/views/modules/timeline-chart/chart.phtml
@@ -3,7 +3,6 @@
use Fisharebest\Webtrees\Age;
use Fisharebest\Webtrees\Fact;
use Fisharebest\Webtrees\Family;
-use Fisharebest\Webtrees\Functions\FunctionsPrint;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
@@ -340,7 +339,7 @@ use Fisharebest\Webtrees\Individual;
echo $event->label();
echo ' — ';
if ($record instanceof Individual) {
- echo FunctionsPrint::formatFactDate($event, $record, false, false);
+ echo view('fact-date', ['cal_link' => 'false', 'fact' => $event, 'record' => $record, 'time' => false]);
} elseif ($record instanceof Family) {
echo $gdate->display();
diff --git a/resources/views/note-page-details.phtml b/resources/views/note-page-details.phtml
index 2a62695a35..f7a516ff47 100644
--- a/resources/views/note-page-details.phtml
+++ b/resources/views/note-page-details.phtml
@@ -2,7 +2,6 @@
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Fact;
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\Http\RequestHandlers\EditNotePage;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Note;
@@ -22,7 +21,7 @@ use Illuminate\Support\Collection;
<th scope="row">
<?= I18N::translate('Shared note') ?>
<?php if (Auth::isEditor($record->tree())) : ?>
- <div class="editfacts nowrap">
+ <div class="pt-2 wt-fact-edit-links">
<a class="btn btn-link" href="<?= e(route(EditNotePage::class, ['xref' => $record->xref(), 'tree' => $record->tree()->name()])) ?>" title="<?= I18N::translate('Edit') ?>">
<?= view('icons/edit') ?>
<span class="visually-hidden">
@@ -39,7 +38,7 @@ use Illuminate\Support\Collection;
<?php foreach ($record->facts() as $fact) : ?>
<?php if ($fact->tag() !== 'NOTE:CONT') : ?>
- <?php FunctionsPrintFacts::printFact($fact, $record) ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $record]) ?>
<?php endif ?>
<?php endforeach ?>
</table>
diff --git a/resources/views/record-page-details.phtml b/resources/views/record-page-details.phtml
index e20e26f219..df978d9bfc 100644
--- a/resources/views/record-page-details.phtml
+++ b/resources/views/record-page-details.phtml
@@ -1,6 +1,5 @@
<?php
-use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\GedcomRecord;
/**
@@ -11,6 +10,6 @@ use Fisharebest\Webtrees\GedcomRecord;
<table class="table wt-facts-table">
<?php foreach ($record->facts([], true) as $fact) : ?>
- <?php FunctionsPrintFacts::printFact($fact, $record) ?>
+ <?= view('fact', ['fact' => $fact, 'record' => $record]) ?>
<?php endforeach ?>
</table>