From 83949fd83e14d92b904067de7271caad7e337f26 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Wed, 9 Jul 2025 17:00:47 +0200 Subject: [PATCH 01/20] render DATE:_TIME the same as DATE:TIME --- app/CustomTags/Heredis.php | 3 +++ resources/views/fact-date.phtml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/CustomTags/Heredis.php b/app/CustomTags/Heredis.php index 0b9341e0d7d..699c5633146 100644 --- a/app/CustomTags/Heredis.php +++ b/app/CustomTags/Heredis.php @@ -24,6 +24,7 @@ use Fisharebest\Webtrees\Elements\CertaintyAssessment; use Fisharebest\Webtrees\Elements\Creation; use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\TimeValue; use Fisharebest\Webtrees\I18N; /** @@ -52,8 +53,10 @@ public function tags(): array { return [ 'FAM:_CREA' => new Creation(I18N::translate('Created at')), + 'FAM:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), 'INDI:_CREA' => new Creation(I18N::translate('Created at')), 'INDI:SIGN' => new CustomElement(I18N::translate('Signature')), + 'INDI:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), 'SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 'SOUR:TYPE' => new CustomElement(I18N::translate('Type')), /* Reported on the forum - but what do they mean? diff --git a/resources/views/fact-date.phtml b/resources/views/fact-date.phtml index 4ef1ab8d719..512648997c8 100644 --- a/resources/views/fact-date.phtml +++ b/resources/views/fact-date.phtml @@ -49,7 +49,7 @@ if (preg_match('/\n2 DATE (.+)/', $factrec, $match) === 1) { $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) === 1) { + if ($time && preg_match('/\n3 [_]?TIME (.+)/', $factrec, $match) === 1) { $html .= ' – ' . $match[1] . ''; } From 88a35144f34e283d283903b47aaccf9e7cdece6a Mon Sep 17 00:00:00 2001 From: BertKoor Date: Thu, 10 Jul 2025 16:13:34 +0200 Subject: [PATCH 02/20] completed list of Heredis custom tags --- app/CustomTags/Heredis.php | 84 +++++++++++++++++++++++++++--- app/Elements/CustomBooleanFact.php | 63 ++++++++++++++++++++++ app/Elements/HeredisFIL.php | 50 ++++++++++++++++++ app/Elements/HeredisFNA.php | 45 ++++++++++++++++ app/Elements/HeredisQualEvid.php | 44 ++++++++++++++++ app/Elements/HeredisQualInfo.php | 43 +++++++++++++++ app/Elements/HeredisQualSour.php | 43 +++++++++++++++ app/Elements/HeredisUST.php | 49 +++++++++++++++++ 8 files changed, 413 insertions(+), 8 deletions(-) create mode 100644 app/Elements/CustomBooleanFact.php create mode 100644 app/Elements/HeredisFIL.php create mode 100644 app/Elements/HeredisFNA.php create mode 100644 app/Elements/HeredisQualEvid.php create mode 100644 app/Elements/HeredisQualInfo.php create mode 100644 app/Elements/HeredisQualSour.php create mode 100644 app/Elements/HeredisUST.php diff --git a/app/CustomTags/Heredis.php b/app/CustomTags/Heredis.php index 699c5633146..bd07f67e5ef 100644 --- a/app/CustomTags/Heredis.php +++ b/app/CustomTags/Heredis.php @@ -21,10 +21,30 @@ use Fisharebest\Webtrees\Contracts\CustomTagInterface; use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\AddressEmail; +use Fisharebest\Webtrees\Elements\AddressWebPage; +use Fisharebest\Webtrees\Elements\AgeAtEvent; use Fisharebest\Webtrees\Elements\CertaintyAssessment; +use Fisharebest\Webtrees\Elements\Coordinates; use Fisharebest\Webtrees\Elements\Creation; +use Fisharebest\Webtrees\Elements\CustomBooleanFact; use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\DateValueExact; +use Fisharebest\Webtrees\Elements\EmptyElement; +use Fisharebest\Webtrees\Elements\HeredisFIL; +use Fisharebest\Webtrees\Elements\HeredisFNA; +use Fisharebest\Webtrees\Elements\HeredisQualEvid; +use Fisharebest\Webtrees\Elements\HeredisQualInfo; +use Fisharebest\Webtrees\Elements\HeredisQualSour; +use Fisharebest\Webtrees\Elements\HeredisUST; +use Fisharebest\Webtrees\Elements\NoteStructure; +use Fisharebest\Webtrees\Elements\PafUid; +use Fisharebest\Webtrees\Elements\PlaceLatitude; +use Fisharebest\Webtrees\Elements\PlaceLongtitude; +use Fisharebest\Webtrees\Elements\PlaceName; +use Fisharebest\Webtrees\Elements\RoleInEvent; use Fisharebest\Webtrees\Elements\TimeValue; +use Fisharebest\Webtrees\Elements\UserReferenceNumber; use Fisharebest\Webtrees\I18N; /** @@ -47,25 +67,73 @@ public function name(): string /** * Tags created by this application. * + * Heredis is predominantly used in France, so keeping unique tag labels in French is a service to its users. + * + * Reference: https://help.heredis.com/les-tags-gedcom/ and https://help.heredis.com/en/gedcom-tags/ + * Example GEDCOM fragment with lots of custom tags: https://www.geneanet.org/forum/viewtopic.php?p=2441735 + * * * @return array */ public function tags(): array { return [ + 'HEAD:_GUID' => new PafUid(I18N::translate('Identifiant du fichier')), 'FAM:_CREA' => new Creation(I18N::translate('Created at')), + 'FAM:_UST' => new HeredisUST(I18N::translate('Statut d’union')), // Union type 'FAM:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), + 'FAM:*:PLAC:_SUBMAP' => new Coordinates(I18N::translate('Géolocalisation des subdivisions')), // Geolocation of subdivisions + 'FAM:*:PLAC:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude') . ' des subdivisions'), + 'FAM:*:PLAC:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude') . ' des subdivisions'), + 'FAM:*:SOUR:_QUAL' => new EmptyElement(I18N::translate('Qualité des citations complètes')), // Quality of completed citations + 'FAM:*:SOUR:_QUAL:_SOUR' => new HeredisQualSour(I18N::translate('Qualité de la source')), // Quality of the source + 'FAM:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Qualité de l’information')), // Quality of the information + 'FAM:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Qualité de la preuve')), // Quality of proof + 'FAM:*:_RECH' => new EmptyElement(I18N::translate('Infos de recherche de l’événement')), // Research Data of an event + 'FAM:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Projet de recherche')), // Research Data Project + 'FAM:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document de recherche')), // Search Document type of Search Data tab + 'FAM:*:_RECH:PLAC' => new PlaceName(I18N::translate('Lieu de recherche')), // Search Place of Search Data tab + 'FAM:*:_RECH:DATE' => new DateValueExact(I18N::translate('Date de recherche')), // Search date of Search Data tab + 'FAM:*:_RECH:REFN' => new UserReferenceNumber(I18N::translate('Référence de la recherche')), // Search data call number + 'FAM:*:_RECH:WWW' => new AddressWebPage(I18N::translate('Site web de la recherche')), // Search data website field + 'FAM:*:_RECH:NOTE' => new NoteStructure(I18N::translate('Note de recherche')), // Research note + 'INDI:_CLS' => new CustomBooleanFact(I18N::translate('Individu sans postérité')), // Person without descendants 'INDI:_CREA' => new Creation(I18N::translate('Created at')), - 'INDI:SIGN' => new CustomElement(I18N::translate('Signature')), + 'INDI:_FIL' => new HeredisFIL(I18N::translate('Filiation de l’individu')), // Child Status + 'INDI:_FNF' => new CustomBooleanFact(I18N::translate('Père introuvable')), // Father not found, untraceable + 'INDI:_MNF' => new CustomBooleanFact(I18N::translate('Mère introuvable')), // Mother not found, untraceable + 'INDI:_SEC' => new CustomBooleanFact(I18N::translate('Individu secondaire')), // Secondary person + 'INDI:_ULS' => new CustomBooleanFact(I18N::translate('Individu sans alliance')), // Unmarried person + 'INDI:SIGN' => new CustomBooleanFact(I18N::translate('Signature')), + 'INDI:ASSO:_AGE' => new AgeAtEvent(I18N::translate('Age')), + 'INDI:ASSO:_ROLE' => new RoleInEvent(I18N::translate('Role')), + 'INDI:ASSO:_TITL' => new CustomElement(I18N::translate('Title')), + 'INDI:ASSO:_TYPE' => new CustomElement(I18N::translate('Type')), 'INDI:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), + 'INDI:*:PLAC:_SUBMAP' => new Coordinates(I18N::translate('Géolocalisation des subdivisions')), // Geolocation of subdivisions + 'INDI:*:PLAC:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude') . ' des subdivisions'), + 'INDI:*:PLAC:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude') . ' des subdivisions'), + 'INDI:*:SOUR:_QUAL' => new EmptyElement(I18N::translate('Qualité des citations complètes')), // Quality of completed citations + 'INDI:*:SOUR:_QUAL:_SOUR' => new HeredisQualSour(I18N::translate('Qualité de la source')), // Quality of the source + 'INDI:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Qualité de l’information')), // Quality of the information + 'INDI:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Qualité de la preuve')), // Quality of proof + 'INDI:*:_ETI' => new CustomElement(I18N::translate('Etiquettes personnalisées')), // Personalized flags + 'INDI:*:_FNA' => new HeredisFNA(I18N::translate('Etat des recherches d’un événement')), // Research Status of an event + 'INDI:*:_RECH' => new EmptyElement(I18N::translate('Infos de recherche de l’événement')), // Research Data of an event + 'INDI:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Projet de recherche')), // Research Data Project + 'INDI:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document de recherche')), // Search Document type of Search Data tab + 'INDI:*:_RECH:PLAC' => new PlaceName(I18N::translate('Lieu de recherche')), // Search Place of Search Data tab + 'INDI:*:_RECH:DATE' => new DateValueExact(I18N::translate('Date de recherche')), // Search date of Search Data tab + 'INDI:*:_RECH:REFN' => new UserReferenceNumber(I18N::translate('Référence de la recherche')), // Search data call number + 'INDI:*:_RECH:WWW' => new AddressWebPage(I18N::translate('Site web de la recherche')), // Search data website field + 'INDI:*:_RECH:NOTE' => new NoteStructure(I18N::translate('Note de recherche')), // Research note + 'NOTE:_CREA' => new Creation(I18N::translate('Created at')), + 'OBJE:_CREA' => new Creation(I18N::translate('Created at')), + 'REPO:_CREA' => new Creation(I18N::translate('Created at')), + 'SOUR:EMAIL' => new AddressEmail(I18N::translate('Email address')), 'SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 'SOUR:TYPE' => new CustomElement(I18N::translate('Type')), - /* Reported on the forum - but what do they mean? - 'INDI:_FIL' => new CustomElement(I18N::translate('???')), - 'INDI:*:_FNA' => new CustomElement(I18N::translate('???')), - 'INDI:????:????:_SUBMAP' => new EmptyElement(I18N::translate('Coordinates'), ['INDI' => '1:1', 'LONG' => '1:1']), - 'INDI:????:????:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude')), - 'INDI:????:????:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude')), - */ + 'SOUR:_ARCH' => new CustomElement(I18N::translate('Classement')), // Archive + 'SOUR:_CREA' => new Creation(I18N::translate('Created at')), ]; } } diff --git a/app/Elements/CustomBooleanFact.php b/app/Elements/CustomBooleanFact.php new file mode 100644 index 00000000000..90202e53e2e --- /dev/null +++ b/app/Elements/CustomBooleanFact.php @@ -0,0 +1,63 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; + +/** + * CustomBooleanFact, leniently accepting values yes and no, true and false, 1 and 0, in uppercase or lowercase. + */ +class CustomBooleanFact extends AbstractEventElement +{ + + /** + * Convert a value to a canonical form. + * + * @param string $value + * + * @return string + */ + public function canonical(string $value): string + { + $value = strtoupper(parent::canonical($value)); + if (in_array($value, ['YES', 'TRUE', '1'])) { + return 'Y'; + } + if (in_array($value, ['NO', 'FALSE', '0'])) { + return 'N'; + } + + return $value; + } + + /** + * A list of controlled values for this element + * + * @return array + */ + public function values(): array + { + return [ + 'Y' => I18N::translate('Yes'), + 'N' => I18N::translate('No'), + ]; + } + +} diff --git a/app/Elements/HeredisFIL.php b/app/Elements/HeredisFIL.php new file mode 100644 index 00000000000..52d0e567e68 --- /dev/null +++ b/app/Elements/HeredisFIL.php @@ -0,0 +1,50 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; + +/** + * Heredis custom tag INDI:_FIL - Child status + */ +class HeredisFIL extends AbstractEventElement +{ + + /** + * A list of controlled values for this element + * + * @return array + */ + public function values(): array + { + return [ + 'LEGITIMATE_CHILD' => I18N::translate('Légitime'), + 'NATURAL_CHILD' => I18N::translate('Naturel'), + 'RECOGNIZED_CHILD' => I18N::translate('Reconnu'), + 'LEGITIMIZED_CHILD' => I18N::translate('Légitimé'), + 'CHILD_FOUND' => I18N::translate('Trouvé'), + 'ADOPTED_CHILD' => I18N::translate('Adopté'), + 'ADULTEROUS_CHILD' => I18N::translate('Adultérin'), + 'STILLBORN_CHILD' => I18N::translate('Mort-Né'), + 'RELATIONSHIP_UNKNOW' => I18N::translate('Non Connue'), + ]; + } + +} diff --git a/app/Elements/HeredisFNA.php b/app/Elements/HeredisFNA.php new file mode 100644 index 00000000000..3816454b2f3 --- /dev/null +++ b/app/Elements/HeredisFNA.php @@ -0,0 +1,45 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; + +/** + * Heredis custom tag INDI:*:_FNA - Research status + */ +class HeredisFNA extends AbstractEventElement +{ + + /** + * A list of controlled values for this element + * + * @return array + */ + public function values(): array + { + return [ + 'NO' => I18N::translate('Ne pas rechercher'), + 'YES' => I18N::translate('Faire des recherches'), + 'NOT_FOUND' => I18N::translate('Introuvable'), + 'IN_PROGRESS' => I18N::translate('Recherches en cours'), + ]; + } + +} diff --git a/app/Elements/HeredisQualEvid.php b/app/Elements/HeredisQualEvid.php new file mode 100644 index 00000000000..c610772615b --- /dev/null +++ b/app/Elements/HeredisQualEvid.php @@ -0,0 +1,44 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; + +/** + * Heredis custom tag *:*:SOUR:_QUAL:_EVID - quality of the evidence + */ +class HeredisQualEvid extends AbstractEventElement +{ + + /** + * A list of controlled values for this element + * + * @return array + */ + public function values(): array + { + return [ + 'D' => I18N::translate('Directe'), + 'I' => I18N::translate('Indirecte'), + 'N' => I18N::translate('Negative'), + ]; + } + +} diff --git a/app/Elements/HeredisQualInfo.php b/app/Elements/HeredisQualInfo.php new file mode 100644 index 00000000000..207aa80a031 --- /dev/null +++ b/app/Elements/HeredisQualInfo.php @@ -0,0 +1,43 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; + +/** + * Heredis custom tag *:*:SOUR:_QUAL:_INFO - quality of the information + */ +class HeredisQualInfo extends AbstractEventElement +{ + + /** + * A list of controlled values for this element + * + * @return array + */ + public function values(): array + { + return [ + 'P' => I18N::translate('Primaire'), + 'S' => I18N::translate('Secondaire'), + ]; + } + +} diff --git a/app/Elements/HeredisQualSour.php b/app/Elements/HeredisQualSour.php new file mode 100644 index 00000000000..16419db3749 --- /dev/null +++ b/app/Elements/HeredisQualSour.php @@ -0,0 +1,43 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; + +/** + * Heredis custom tag *:*:SOUR:_QUAL:_SOUR - quality of the source + */ +class HeredisQualSour extends AbstractEventElement +{ + + /** + * A list of controlled values for this element + * + * @return array + */ + public function values(): array + { + return [ + 'O' => I18N::translate('Originale'), + 'D' => I18N::translate('Dérivé'), + ]; + } + +} diff --git a/app/Elements/HeredisUST.php b/app/Elements/HeredisUST.php new file mode 100644 index 00000000000..edd23fe2cc8 --- /dev/null +++ b/app/Elements/HeredisUST.php @@ -0,0 +1,49 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; + +/** + * Heredis custom tag FAM:_UST - Union status + */ +class HeredisUST extends AbstractEventElement +{ + + /** + * A list of controlled values for this element + * + * @return array + */ + public function values(): array + { + return [ + 'MARRIED' => I18N::translate('Mariage'), + 'ENGAGEMENT' => I18N::translate('Fiançailles'), + 'SEPARATED' => I18N::translate('Séparation'), + 'DIVORCED' => I18N::translate('Divorce'), + 'COMMON_LAW' => I18N::translate('Autre union officielle'), + 'COHABITATION' => I18N::translate('Union libre'), + 'UNKNOWN' => I18N::translate('Statut d’union inconnu'), + 'OTHER' => I18N::translate('Autre statut'), + ]; + } + +} From 933570039d974548679196785c5c5429f9d9794e Mon Sep 17 00:00:00 2001 From: BertKoor Date: Thu, 10 Jul 2025 16:18:24 +0200 Subject: [PATCH 03/20] LATI/LONG tags swapped to their natural order --- app/Elements/Coordinates.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Elements/Coordinates.php b/app/Elements/Coordinates.php index 1025d19840c..4965b207676 100644 --- a/app/Elements/Coordinates.php +++ b/app/Elements/Coordinates.php @@ -25,7 +25,7 @@ class Coordinates extends EmptyElement { protected const array SUBTAGS = [ - 'LONG' => '1:1', 'LATI' => '1:1', + 'LONG' => '1:1', ]; } From 164c009644353bdb30026808f2b56014ec33af5d Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 11 Jul 2025 08:41:36 +0200 Subject: [PATCH 04/20] moved some Heredis custom tags to Extra Information pane --- app/Module/IndividualMetadataModule.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/Module/IndividualMetadataModule.php b/app/Module/IndividualMetadataModule.php index 74f496ef14e..915d41cb2a2 100644 --- a/app/Module/IndividualMetadataModule.php +++ b/app/Module/IndividualMetadataModule.php @@ -45,10 +45,18 @@ class IndividualMetadataModule extends AbstractModule implements ModuleSidebarIn 'RESN', 'RFN', 'RIN', + 'SIGN', 'SSN', 'SUBM', - '_UID', + '_CLS', + '_CREA', + '_FIL', '_FSFTID', + '_FNF', + '_MNF', + '_SEC', + '_UID', + '_ULS', '_WEBTAG', ]; From 3456f0038e9692c5c7815938910b7809d86a1a22 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 11 Jul 2025 09:31:07 +0200 Subject: [PATCH 05/20] custom subtags should extend AbstractElement, not AbstractEventElement --- app/Elements/HeredisFIL.php | 2 +- app/Elements/HeredisFNA.php | 2 +- app/Elements/HeredisQualEvid.php | 2 +- app/Elements/HeredisQualInfo.php | 2 +- app/Elements/HeredisQualSour.php | 2 +- app/Elements/HeredisUST.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Elements/HeredisFIL.php b/app/Elements/HeredisFIL.php index 52d0e567e68..724d3fdd9ac 100644 --- a/app/Elements/HeredisFIL.php +++ b/app/Elements/HeredisFIL.php @@ -24,7 +24,7 @@ /** * Heredis custom tag INDI:_FIL - Child status */ -class HeredisFIL extends AbstractEventElement +class HeredisFIL extends AbstractElement { /** diff --git a/app/Elements/HeredisFNA.php b/app/Elements/HeredisFNA.php index 3816454b2f3..1ce4262f6d6 100644 --- a/app/Elements/HeredisFNA.php +++ b/app/Elements/HeredisFNA.php @@ -24,7 +24,7 @@ /** * Heredis custom tag INDI:*:_FNA - Research status */ -class HeredisFNA extends AbstractEventElement +class HeredisFNA extends AbstractElement { /** diff --git a/app/Elements/HeredisQualEvid.php b/app/Elements/HeredisQualEvid.php index c610772615b..64de5169fbd 100644 --- a/app/Elements/HeredisQualEvid.php +++ b/app/Elements/HeredisQualEvid.php @@ -24,7 +24,7 @@ /** * Heredis custom tag *:*:SOUR:_QUAL:_EVID - quality of the evidence */ -class HeredisQualEvid extends AbstractEventElement +class HeredisQualEvid extends AbstractElement { /** diff --git a/app/Elements/HeredisQualInfo.php b/app/Elements/HeredisQualInfo.php index 207aa80a031..7e00560a190 100644 --- a/app/Elements/HeredisQualInfo.php +++ b/app/Elements/HeredisQualInfo.php @@ -24,7 +24,7 @@ /** * Heredis custom tag *:*:SOUR:_QUAL:_INFO - quality of the information */ -class HeredisQualInfo extends AbstractEventElement +class HeredisQualInfo extends AbstractElement { /** diff --git a/app/Elements/HeredisQualSour.php b/app/Elements/HeredisQualSour.php index 16419db3749..16d24135714 100644 --- a/app/Elements/HeredisQualSour.php +++ b/app/Elements/HeredisQualSour.php @@ -24,7 +24,7 @@ /** * Heredis custom tag *:*:SOUR:_QUAL:_SOUR - quality of the source */ -class HeredisQualSour extends AbstractEventElement +class HeredisQualSour extends AbstractElement { /** diff --git a/app/Elements/HeredisUST.php b/app/Elements/HeredisUST.php index edd23fe2cc8..8d3ab4e01aa 100644 --- a/app/Elements/HeredisUST.php +++ b/app/Elements/HeredisUST.php @@ -24,7 +24,7 @@ /** * Heredis custom tag FAM:_UST - Union status */ -class HeredisUST extends AbstractEventElement +class HeredisUST extends AbstractElement { /** From 53cbdfbb3317e9e04bfca281c1bf367c06a1b14a Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 11 Jul 2025 09:33:35 +0200 Subject: [PATCH 06/20] Heredis research information should be collapsable (wip) --- app/CustomTags/Heredis.php | 5 +- app/Elements/HeredisRechElement.php | 77 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 app/Elements/HeredisRechElement.php diff --git a/app/CustomTags/Heredis.php b/app/CustomTags/Heredis.php index bd07f67e5ef..df00eed7d2e 100644 --- a/app/CustomTags/Heredis.php +++ b/app/CustomTags/Heredis.php @@ -36,6 +36,7 @@ use Fisharebest\Webtrees\Elements\HeredisQualEvid; use Fisharebest\Webtrees\Elements\HeredisQualInfo; use Fisharebest\Webtrees\Elements\HeredisQualSour; +use Fisharebest\Webtrees\Elements\HeredisRechElement; use Fisharebest\Webtrees\Elements\HeredisUST; use Fisharebest\Webtrees\Elements\NoteStructure; use Fisharebest\Webtrees\Elements\PafUid; @@ -117,8 +118,8 @@ public function tags(): array 'INDI:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Qualité de l’information')), // Quality of the information 'INDI:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Qualité de la preuve')), // Quality of proof 'INDI:*:_ETI' => new CustomElement(I18N::translate('Etiquettes personnalisées')), // Personalized flags - 'INDI:*:_FNA' => new HeredisFNA(I18N::translate('Etat des recherches d’un événement')), // Research Status of an event - 'INDI:*:_RECH' => new EmptyElement(I18N::translate('Infos de recherche de l’événement')), // Research Data of an event + 'INDI:*:_FNA' => new HeredisFNA(I18N::translate('Etat des recherches')), // Research Status of an event + 'INDI:*:_RECH' => new HeredisRechElement(I18N::translate('Infos de recherche')), // Research Data of an event 'INDI:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Projet de recherche')), // Research Data Project 'INDI:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document de recherche')), // Search Document type of Search Data tab 'INDI:*:_RECH:PLAC' => new PlaceName(I18N::translate('Lieu de recherche')), // Search Place of Search Data tab diff --git a/app/Elements/HeredisRechElement.php b/app/Elements/HeredisRechElement.php new file mode 100644 index 00000000000..79da3020fad --- /dev/null +++ b/app/Elements/HeredisRechElement.php @@ -0,0 +1,77 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use Fisharebest\Webtrees\I18N; +use Fisharebest\Webtrees\Tree; + +/** + * Heredis custom tag INDI:_FIL - Child status + */ +class HeredisRechElement extends EmptyElement +{ + + protected const array SUBTAGS = [ + '_PROJ' => '0:1', + 'TYPE' => '0:1', + 'PLAC' => '0:1', + 'DATE' => '0:1', + 'REFN' => '0:1', + 'WWW' => '0:1', + 'NOTE' => '0:1', + ]; + + /** + * Convert a value to a canonical form. + * + * @param string $value + * + * @return string + */ + public function canonical(string $value): string + { + return 'N'; + } + + /** + * An edit control for this data. + * + * @param string $id + * @param string $name + * @param string $value + * + * @return string + */ + public function editTextArea(string $id, string $name, string $value): string + { + return ' '; + } + + /** + * Should we collapse the children of this element when editing? + * + * @return bool + */ + public function collapseChildren(): bool + { + return true; + } + +} From 350bda9cbb2fd6d43d201f7dac2db8f838287de6 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Mon, 14 Jul 2025 09:58:19 +0200 Subject: [PATCH 07/20] use yes/no instead of Yes/No because this pair is in the same casing (Yes translates to yes in lower case) --- app/Elements/CustomBooleanFact.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Elements/CustomBooleanFact.php b/app/Elements/CustomBooleanFact.php index 90202e53e2e..a6122adeb67 100644 --- a/app/Elements/CustomBooleanFact.php +++ b/app/Elements/CustomBooleanFact.php @@ -55,8 +55,8 @@ public function canonical(string $value): string public function values(): array { return [ - 'Y' => I18N::translate('Yes'), - 'N' => I18N::translate('No'), + 'Y' => I18N::translate('yes'), + 'N' => I18N::translate('no'), ]; } From f96603cb50e12f24af44773a77088bf7a8be41df Mon Sep 17 00:00:00 2001 From: BertKoor Date: Mon, 14 Jul 2025 11:27:29 +0200 Subject: [PATCH 08/20] labels of Heredis tags changed to English, use I18N to translate back to French --- app/CustomTags/Heredis.php | 92 ++++++++++++++--------------- app/Elements/HeredisFIL.php | 18 +++--- app/Elements/HeredisFNA.php | 8 +-- app/Elements/HeredisQualEvid.php | 4 +- app/Elements/HeredisQualInfo.php | 4 +- app/Elements/HeredisQualSour.php | 4 +- app/Elements/HeredisRechElement.php | 32 +--------- app/Elements/HeredisUST.php | 14 ++--- 8 files changed, 74 insertions(+), 102 deletions(-) diff --git a/app/CustomTags/Heredis.php b/app/CustomTags/Heredis.php index df00eed7d2e..9d017cd0a8f 100644 --- a/app/CustomTags/Heredis.php +++ b/app/CustomTags/Heredis.php @@ -44,6 +44,7 @@ use Fisharebest\Webtrees\Elements\PlaceLongtitude; use Fisharebest\Webtrees\Elements\PlaceName; use Fisharebest\Webtrees\Elements\RoleInEvent; +use Fisharebest\Webtrees\Elements\SourceCallNumber; use Fisharebest\Webtrees\Elements\TimeValue; use Fisharebest\Webtrees\Elements\UserReferenceNumber; use Fisharebest\Webtrees\I18N; @@ -52,6 +53,9 @@ * GEDCOM files created by Heredis * * @see https://www.heredis.com + * + * Reference: https://help.heredis.com/les-tags-gedcom/ and https://help.heredis.com/en/gedcom-tags/ + * Example GEDCOM fragment with lots of custom tags: https://www.geneanet.org/forum/viewtopic.php?p=2441735 */ class Heredis implements CustomTagInterface { @@ -68,72 +72,68 @@ public function name(): string /** * Tags created by this application. * - * Heredis is predominantly used in France, so keeping unique tag labels in French is a service to its users. - * - * Reference: https://help.heredis.com/les-tags-gedcom/ and https://help.heredis.com/en/gedcom-tags/ - * Example GEDCOM fragment with lots of custom tags: https://www.geneanet.org/forum/viewtopic.php?p=2441735 - * * * @return array */ public function tags(): array { return [ - 'HEAD:_GUID' => new PafUid(I18N::translate('Identifiant du fichier')), + 'HEAD:_GUID' => new PafUid(I18N::translate('File identifier')), 'FAM:_CREA' => new Creation(I18N::translate('Created at')), - 'FAM:_UST' => new HeredisUST(I18N::translate('Statut d’union')), // Union type + 'FAM:_UST' => new HeredisUST(I18N::translate('Union type')), 'FAM:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), - 'FAM:*:PLAC:_SUBMAP' => new Coordinates(I18N::translate('Géolocalisation des subdivisions')), // Geolocation of subdivisions - 'FAM:*:PLAC:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude') . ' des subdivisions'), - 'FAM:*:PLAC:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude') . ' des subdivisions'), - 'FAM:*:SOUR:_QUAL' => new EmptyElement(I18N::translate('Qualité des citations complètes')), // Quality of completed citations - 'FAM:*:SOUR:_QUAL:_SOUR' => new HeredisQualSour(I18N::translate('Qualité de la source')), // Quality of the source - 'FAM:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Qualité de l’information')), // Quality of the information - 'FAM:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Qualité de la preuve')), // Quality of proof - 'FAM:*:_RECH' => new EmptyElement(I18N::translate('Infos de recherche de l’événement')), // Research Data of an event - 'FAM:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Projet de recherche')), // Research Data Project - 'FAM:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document de recherche')), // Search Document type of Search Data tab - 'FAM:*:_RECH:PLAC' => new PlaceName(I18N::translate('Lieu de recherche')), // Search Place of Search Data tab - 'FAM:*:_RECH:DATE' => new DateValueExact(I18N::translate('Date de recherche')), // Search date of Search Data tab - 'FAM:*:_RECH:REFN' => new UserReferenceNumber(I18N::translate('Référence de la recherche')), // Search data call number - 'FAM:*:_RECH:WWW' => new AddressWebPage(I18N::translate('Site web de la recherche')), // Search data website field - 'FAM:*:_RECH:NOTE' => new NoteStructure(I18N::translate('Note de recherche')), // Research note - 'INDI:_CLS' => new CustomBooleanFact(I18N::translate('Individu sans postérité')), // Person without descendants + 'FAM:*:PLAC:_SUBMAP' => new Coordinates(I18N::translate('Geolocation of subdivisions')), + 'FAM:*:PLAC:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude of subdivision')), + 'FAM:*:PLAC:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude of subdivision')), + 'FAM:*:SOUR:_QUAL' => new EmptyElement(I18N::translate('Quality of completed citation')), + 'FAM:*:SOUR:_QUAL:_SOUR' => new HeredisQualSour(I18N::translate('Quality of the source')), + 'FAM:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Quality of the information')), + 'FAM:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Quality of the evidence')), + 'FAM:*:_RECH' => new EmptyElement(I18N::translate('Research data')), + 'FAM:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Research project')), + 'FAM:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document')), + 'FAM:*:_RECH:PLAC' => new PlaceName(I18N::translate('Search place')), + 'FAM:*:_RECH:DATE' => new DateValueExact(I18N::translate('Search date')), + 'FAM:*:_RECH:REFN' => new UserReferenceNumber(I18N::translate('Call number')), + 'FAM:*:_RECH:WWW' => new AddressWebPage(I18N::translate('URL')), + 'FAM:*:_RECH:NOTE' => new NoteStructure(I18N::translate('Note')), + 'INDI:_CLS' => new CustomBooleanFact(I18N::translate('Childless')), 'INDI:_CREA' => new Creation(I18N::translate('Created at')), - 'INDI:_FIL' => new HeredisFIL(I18N::translate('Filiation de l’individu')), // Child Status - 'INDI:_FNF' => new CustomBooleanFact(I18N::translate('Père introuvable')), // Father not found, untraceable - 'INDI:_MNF' => new CustomBooleanFact(I18N::translate('Mère introuvable')), // Mother not found, untraceable - 'INDI:_SEC' => new CustomBooleanFact(I18N::translate('Individu secondaire')), // Secondary person - 'INDI:_ULS' => new CustomBooleanFact(I18N::translate('Individu sans alliance')), // Unmarried person + 'INDI:_FIL' => new HeredisFIL(I18N::translate('Child status')), + 'INDI:_ETI' => new CustomElement(I18N::translate('Personalized flag')), + 'INDI:_FNF' => new CustomBooleanFact(I18N::translate('Untraceable father')), + 'INDI:_MNF' => new CustomBooleanFact(I18N::translate('Untraceable mother')), + 'INDI:_SEC' => new CustomBooleanFact(I18N::translate('Secondary person')), + 'INDI:_ULS' => new CustomBooleanFact(I18N::translate('Unmarried')), 'INDI:SIGN' => new CustomBooleanFact(I18N::translate('Signature')), 'INDI:ASSO:_AGE' => new AgeAtEvent(I18N::translate('Age')), 'INDI:ASSO:_ROLE' => new RoleInEvent(I18N::translate('Role')), 'INDI:ASSO:_TITL' => new CustomElement(I18N::translate('Title')), 'INDI:ASSO:_TYPE' => new CustomElement(I18N::translate('Type')), 'INDI:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), - 'INDI:*:PLAC:_SUBMAP' => new Coordinates(I18N::translate('Géolocalisation des subdivisions')), // Geolocation of subdivisions - 'INDI:*:PLAC:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude') . ' des subdivisions'), - 'INDI:*:PLAC:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude') . ' des subdivisions'), - 'INDI:*:SOUR:_QUAL' => new EmptyElement(I18N::translate('Qualité des citations complètes')), // Quality of completed citations - 'INDI:*:SOUR:_QUAL:_SOUR' => new HeredisQualSour(I18N::translate('Qualité de la source')), // Quality of the source - 'INDI:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Qualité de l’information')), // Quality of the information - 'INDI:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Qualité de la preuve')), // Quality of proof - 'INDI:*:_ETI' => new CustomElement(I18N::translate('Etiquettes personnalisées')), // Personalized flags - 'INDI:*:_FNA' => new HeredisFNA(I18N::translate('Etat des recherches')), // Research Status of an event - 'INDI:*:_RECH' => new HeredisRechElement(I18N::translate('Infos de recherche')), // Research Data of an event - 'INDI:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Projet de recherche')), // Research Data Project - 'INDI:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document de recherche')), // Search Document type of Search Data tab - 'INDI:*:_RECH:PLAC' => new PlaceName(I18N::translate('Lieu de recherche')), // Search Place of Search Data tab - 'INDI:*:_RECH:DATE' => new DateValueExact(I18N::translate('Date de recherche')), // Search date of Search Data tab - 'INDI:*:_RECH:REFN' => new UserReferenceNumber(I18N::translate('Référence de la recherche')), // Search data call number - 'INDI:*:_RECH:WWW' => new AddressWebPage(I18N::translate('Site web de la recherche')), // Search data website field - 'INDI:*:_RECH:NOTE' => new NoteStructure(I18N::translate('Note de recherche')), // Research note + 'INDI:*:PLAC:_SUBMAP' => new Coordinates(I18N::translate('Geolocation of subdivisions')), + 'INDI:*:PLAC:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude of subdivision')), + 'INDI:*:PLAC:_SUBMAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude of subdivision')), + 'INDI:*:SOUR:_QUAL' => new EmptyElement(I18N::translate('Quality of completed citation')), + 'INDI:*:SOUR:_QUAL:_SOUR' => new HeredisQualSour(I18N::translate('Quality of the source')), + 'INDI:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Quality of the information')), + 'INDI:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Quality of proof')), + 'INDI:*:_ETI' => new CustomElement(I18N::translate('Personalized flag')), + 'INDI:*:_FNA' => new HeredisFNA(I18N::translate('Research status')), + 'INDI:*:_RECH' => new HeredisRechElement(I18N::translate('Research data')), + 'INDI:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Research project')), + 'INDI:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document')), + 'INDI:*:_RECH:PLAC' => new PlaceName(I18N::translate('Search place')), + 'INDI:*:_RECH:DATE' => new DateValueExact(I18N::translate('Search date')), + 'INDI:*:_RECH:REFN' => new SourceCallNumber(I18N::translate('Call number')), + 'INDI:*:_RECH:WWW' => new AddressWebPage(I18N::translate('URL')), + 'INDI:*:_RECH:NOTE' => new NoteStructure(I18N::translate('Note')), 'NOTE:_CREA' => new Creation(I18N::translate('Created at')), 'OBJE:_CREA' => new Creation(I18N::translate('Created at')), 'REPO:_CREA' => new Creation(I18N::translate('Created at')), 'SOUR:EMAIL' => new AddressEmail(I18N::translate('Email address')), 'SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 'SOUR:TYPE' => new CustomElement(I18N::translate('Type')), - 'SOUR:_ARCH' => new CustomElement(I18N::translate('Classement')), // Archive + 'SOUR:_ARCH' => new CustomElement(I18N::translate('Archive')), 'SOUR:_CREA' => new Creation(I18N::translate('Created at')), ]; } diff --git a/app/Elements/HeredisFIL.php b/app/Elements/HeredisFIL.php index 724d3fdd9ac..80246f7106f 100644 --- a/app/Elements/HeredisFIL.php +++ b/app/Elements/HeredisFIL.php @@ -35,15 +35,15 @@ class HeredisFIL extends AbstractElement public function values(): array { return [ - 'LEGITIMATE_CHILD' => I18N::translate('Légitime'), - 'NATURAL_CHILD' => I18N::translate('Naturel'), - 'RECOGNIZED_CHILD' => I18N::translate('Reconnu'), - 'LEGITIMIZED_CHILD' => I18N::translate('Légitimé'), - 'CHILD_FOUND' => I18N::translate('Trouvé'), - 'ADOPTED_CHILD' => I18N::translate('Adopté'), - 'ADULTEROUS_CHILD' => I18N::translate('Adultérin'), - 'STILLBORN_CHILD' => I18N::translate('Mort-Né'), - 'RELATIONSHIP_UNKNOW' => I18N::translate('Non Connue'), + 'LEGITIMATE_CHILD' => I18N::translate('Legitimate'), + 'NATURAL_CHILD' => I18N::translate('Natural'), + 'RECOGNIZED_CHILD' => I18N::translate('Legally recognised'), + 'LEGITIMIZED_CHILD' => I18N::translate('Legitimated'), + 'CHILD_FOUND' => I18N::translate('Foundling'), + 'ADOPTED_CHILD' => I18N::translate('Adopted'), + 'ADULTEROUS_CHILD' => I18N::translate('Illegitimate'), + 'STILLBORN_CHILD' => I18N::translate('Stillborn'), + 'RELATIONSHIP_UNKNOW' => I18N::translate('Unknown'), ]; } diff --git a/app/Elements/HeredisFNA.php b/app/Elements/HeredisFNA.php index 1ce4262f6d6..1e687042e65 100644 --- a/app/Elements/HeredisFNA.php +++ b/app/Elements/HeredisFNA.php @@ -35,10 +35,10 @@ class HeredisFNA extends AbstractElement public function values(): array { return [ - 'NO' => I18N::translate('Ne pas rechercher'), - 'YES' => I18N::translate('Faire des recherches'), - 'NOT_FOUND' => I18N::translate('Introuvable'), - 'IN_PROGRESS' => I18N::translate('Recherches en cours'), + 'NO' => I18N::translate('No search record'), + 'YES' => I18N::translate('Search record'), + 'NOT_FOUND' => I18N::translate('Untraceable record'), + 'IN_PROGRESS' => I18N::translate('Search in progress'), ]; } diff --git a/app/Elements/HeredisQualEvid.php b/app/Elements/HeredisQualEvid.php index 64de5169fbd..da68509d768 100644 --- a/app/Elements/HeredisQualEvid.php +++ b/app/Elements/HeredisQualEvid.php @@ -35,8 +35,8 @@ class HeredisQualEvid extends AbstractElement public function values(): array { return [ - 'D' => I18N::translate('Directe'), - 'I' => I18N::translate('Indirecte'), + 'D' => I18N::translate('Direct'), + 'I' => I18N::translate('Indirect'), 'N' => I18N::translate('Negative'), ]; } diff --git a/app/Elements/HeredisQualInfo.php b/app/Elements/HeredisQualInfo.php index 7e00560a190..7fa3af79f1e 100644 --- a/app/Elements/HeredisQualInfo.php +++ b/app/Elements/HeredisQualInfo.php @@ -35,8 +35,8 @@ class HeredisQualInfo extends AbstractElement public function values(): array { return [ - 'P' => I18N::translate('Primaire'), - 'S' => I18N::translate('Secondaire'), + 'P' => I18N::translate('Primary'), + 'S' => I18N::translate('Secondary'), ]; } diff --git a/app/Elements/HeredisQualSour.php b/app/Elements/HeredisQualSour.php index 16d24135714..dcba42bf38c 100644 --- a/app/Elements/HeredisQualSour.php +++ b/app/Elements/HeredisQualSour.php @@ -35,8 +35,8 @@ class HeredisQualSour extends AbstractElement public function values(): array { return [ - 'O' => I18N::translate('Originale'), - 'D' => I18N::translate('Dérivé'), + 'O' => I18N::translate('Original'), + 'D' => I18N::translate('Derived'), ]; } diff --git a/app/Elements/HeredisRechElement.php b/app/Elements/HeredisRechElement.php index 79da3020fad..b745b25ee4d 100644 --- a/app/Elements/HeredisRechElement.php +++ b/app/Elements/HeredisRechElement.php @@ -19,11 +19,8 @@ namespace Fisharebest\Webtrees\Elements; -use Fisharebest\Webtrees\I18N; -use Fisharebest\Webtrees\Tree; - /** - * Heredis custom tag INDI:_FIL - Child status + * Heredis custom tag *:*:_RECH - Research data of an event. */ class HeredisRechElement extends EmptyElement { @@ -38,34 +35,9 @@ class HeredisRechElement extends EmptyElement 'NOTE' => '0:1', ]; - /** - * Convert a value to a canonical form. - * - * @param string $value - * - * @return string - */ - public function canonical(string $value): string - { - return 'N'; - } - - /** - * An edit control for this data. - * - * @param string $id - * @param string $name - * @param string $value - * - * @return string - */ - public function editTextArea(string $id, string $name, string $value): string - { - return ' '; - } - /** * Should we collapse the children of this element when editing? + * FIXME: label is not shown, it does not have a control to collapse * * @return bool */ diff --git a/app/Elements/HeredisUST.php b/app/Elements/HeredisUST.php index 8d3ab4e01aa..d2289f4f546 100644 --- a/app/Elements/HeredisUST.php +++ b/app/Elements/HeredisUST.php @@ -35,14 +35,14 @@ class HeredisUST extends AbstractElement public function values(): array { return [ - 'MARRIED' => I18N::translate('Mariage'), - 'ENGAGEMENT' => I18N::translate('Fiançailles'), - 'SEPARATED' => I18N::translate('Séparation'), + 'MARRIED' => I18N::translate('Marriage'), + 'ENGAGEMENT' => I18N::translate('Engaged'), + 'SEPARATED' => I18N::translate('Separation'), 'DIVORCED' => I18N::translate('Divorce'), - 'COMMON_LAW' => I18N::translate('Autre union officielle'), - 'COHABITATION' => I18N::translate('Union libre'), - 'UNKNOWN' => I18N::translate('Statut d’union inconnu'), - 'OTHER' => I18N::translate('Autre statut'), + 'COMMON_LAW' => I18N::translate('Other type of marriage'), + 'COHABITATION' => I18N::translate('Cohabitee'), + 'UNKNOWN' => I18N::translate('Unknown family status'), + 'OTHER' => I18N::translate('Other status'), ]; } From c7e649cb9f228d4f07f2aa2c1c3b680c1d4b95a2 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Mon, 14 Jul 2025 11:28:27 +0200 Subject: [PATCH 09/20] moved Heredis 'etiquettes' (personal flags) to Extra Information pane --- app/Module/IndividualMetadataModule.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Module/IndividualMetadataModule.php b/app/Module/IndividualMetadataModule.php index 915d41cb2a2..d03f7ca382d 100644 --- a/app/Module/IndividualMetadataModule.php +++ b/app/Module/IndividualMetadataModule.php @@ -50,6 +50,7 @@ class IndividualMetadataModule extends AbstractModule implements ModuleSidebarIn 'SUBM', '_CLS', '_CREA', + '_ETI', '_FIL', '_FSFTID', '_FNF', From 588803215a75aad90ed1ea2648284f7f98ae5d7e Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 25 Jul 2025 12:17:56 +0200 Subject: [PATCH 10/20] codestyle: removed blank lines --- app/Elements/CustomBooleanFact.php | 2 -- app/Elements/Graduation.php | 2 +- app/Elements/HeredisFIL.php | 2 -- app/Elements/HeredisFNA.php | 2 -- app/Elements/HeredisQualEvid.php | 2 -- app/Elements/HeredisQualInfo.php | 2 -- app/Elements/HeredisQualSour.php | 2 -- app/Elements/HeredisRechElement.php | 2 -- app/Elements/HeredisUST.php | 2 -- 9 files changed, 1 insertion(+), 17 deletions(-) diff --git a/app/Elements/CustomBooleanFact.php b/app/Elements/CustomBooleanFact.php index a6122adeb67..42d2012d86a 100644 --- a/app/Elements/CustomBooleanFact.php +++ b/app/Elements/CustomBooleanFact.php @@ -26,7 +26,6 @@ */ class CustomBooleanFact extends AbstractEventElement { - /** * Convert a value to a canonical form. * @@ -59,5 +58,4 @@ public function values(): array 'N' => I18N::translate('no'), ]; } - } diff --git a/app/Elements/Graduation.php b/app/Elements/Graduation.php index 39583e141d0..d466d42f144 100644 --- a/app/Elements/Graduation.php +++ b/app/Elements/Graduation.php @@ -25,7 +25,7 @@ class Graduation extends AbstractEventElement { protected const array SUBTAGS = [ - 'TYPE' => '0:1:?', + 'TYPE' => '0:1', 'DATE' => '0:1', 'AGE' => '0:1', 'PLAC' => '0:1', diff --git a/app/Elements/HeredisFIL.php b/app/Elements/HeredisFIL.php index 80246f7106f..cf1908ed78a 100644 --- a/app/Elements/HeredisFIL.php +++ b/app/Elements/HeredisFIL.php @@ -26,7 +26,6 @@ */ class HeredisFIL extends AbstractElement { - /** * A list of controlled values for this element * @@ -46,5 +45,4 @@ public function values(): array 'RELATIONSHIP_UNKNOW' => I18N::translate('Unknown'), ]; } - } diff --git a/app/Elements/HeredisFNA.php b/app/Elements/HeredisFNA.php index 1e687042e65..cb38fd3ed5d 100644 --- a/app/Elements/HeredisFNA.php +++ b/app/Elements/HeredisFNA.php @@ -26,7 +26,6 @@ */ class HeredisFNA extends AbstractElement { - /** * A list of controlled values for this element * @@ -41,5 +40,4 @@ public function values(): array 'IN_PROGRESS' => I18N::translate('Search in progress'), ]; } - } diff --git a/app/Elements/HeredisQualEvid.php b/app/Elements/HeredisQualEvid.php index da68509d768..b9ced963fc0 100644 --- a/app/Elements/HeredisQualEvid.php +++ b/app/Elements/HeredisQualEvid.php @@ -26,7 +26,6 @@ */ class HeredisQualEvid extends AbstractElement { - /** * A list of controlled values for this element * @@ -40,5 +39,4 @@ public function values(): array 'N' => I18N::translate('Negative'), ]; } - } diff --git a/app/Elements/HeredisQualInfo.php b/app/Elements/HeredisQualInfo.php index 7fa3af79f1e..3c38028bb6b 100644 --- a/app/Elements/HeredisQualInfo.php +++ b/app/Elements/HeredisQualInfo.php @@ -26,7 +26,6 @@ */ class HeredisQualInfo extends AbstractElement { - /** * A list of controlled values for this element * @@ -39,5 +38,4 @@ public function values(): array 'S' => I18N::translate('Secondary'), ]; } - } diff --git a/app/Elements/HeredisQualSour.php b/app/Elements/HeredisQualSour.php index dcba42bf38c..64a3f6b0619 100644 --- a/app/Elements/HeredisQualSour.php +++ b/app/Elements/HeredisQualSour.php @@ -26,7 +26,6 @@ */ class HeredisQualSour extends AbstractElement { - /** * A list of controlled values for this element * @@ -39,5 +38,4 @@ public function values(): array 'D' => I18N::translate('Derived'), ]; } - } diff --git a/app/Elements/HeredisRechElement.php b/app/Elements/HeredisRechElement.php index b745b25ee4d..6484a473945 100644 --- a/app/Elements/HeredisRechElement.php +++ b/app/Elements/HeredisRechElement.php @@ -24,7 +24,6 @@ */ class HeredisRechElement extends EmptyElement { - protected const array SUBTAGS = [ '_PROJ' => '0:1', 'TYPE' => '0:1', @@ -45,5 +44,4 @@ public function collapseChildren(): bool { return true; } - } diff --git a/app/Elements/HeredisUST.php b/app/Elements/HeredisUST.php index d2289f4f546..545895a2e88 100644 --- a/app/Elements/HeredisUST.php +++ b/app/Elements/HeredisUST.php @@ -26,7 +26,6 @@ */ class HeredisUST extends AbstractElement { - /** * A list of controlled values for this element * @@ -45,5 +44,4 @@ public function values(): array 'OTHER' => I18N::translate('Other status'), ]; } - } From 761f3225d9c507e706f5aa409ca61c30557a75e5 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 25 Jul 2025 13:30:53 +0200 Subject: [PATCH 11/20] codecov: fixed missing tests --- tests/app/CustomTags/HeredisTest.php | 8 ++++ tests/app/Elements/CustomBooleanFactTest.php | 41 +++++++++++++++++++ tests/app/Elements/HeredisFILTest.php | 39 ++++++++++++++++++ tests/app/Elements/HeredisFNATest.php | 39 ++++++++++++++++++ tests/app/Elements/HeredisQualEvidTest.php | 39 ++++++++++++++++++ tests/app/Elements/HeredisQualInfoTest.php | 39 ++++++++++++++++++ tests/app/Elements/HeredisQualSourTest.php | 39 ++++++++++++++++++ tests/app/Elements/HeredisRechElementTest.php | 34 +++++++++++++++ tests/app/Elements/HeredisUSTTest.php | 39 ++++++++++++++++++ 9 files changed, 317 insertions(+) create mode 100644 tests/app/Elements/CustomBooleanFactTest.php create mode 100644 tests/app/Elements/HeredisFILTest.php create mode 100644 tests/app/Elements/HeredisFNATest.php create mode 100644 tests/app/Elements/HeredisQualEvidTest.php create mode 100644 tests/app/Elements/HeredisQualInfoTest.php create mode 100644 tests/app/Elements/HeredisQualSourTest.php create mode 100644 tests/app/Elements/HeredisRechElementTest.php create mode 100644 tests/app/Elements/HeredisUSTTest.php diff --git a/tests/app/CustomTags/HeredisTest.php b/tests/app/CustomTags/HeredisTest.php index 3fcc57d7615..6375ba8bae1 100644 --- a/tests/app/CustomTags/HeredisTest.php +++ b/tests/app/CustomTags/HeredisTest.php @@ -29,4 +29,12 @@ public function testClass(): void { self::assertTrue(class_exists(Heredis::class)); } + + public function testHeredis(): void + { + $heredis = new Heredis(); + self::assertIsString($heredis->name()); + self::assertArrayHasKey('HEAD:_GUID', $heredis->tags()); + self::assertArrayHasKey('SOUR:_CREA', $heredis->tags()); + } } diff --git a/tests/app/Elements/CustomBooleanFactTest.php b/tests/app/Elements/CustomBooleanFactTest.php new file mode 100644 index 00000000000..c6d149116e8 --- /dev/null +++ b/tests/app/Elements/CustomBooleanFactTest.php @@ -0,0 +1,41 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(CustomBooleanFact::class)] +class CustomBooleanFactTest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new CustomBooleanFact('label'); + } + + public function testCanonical(): void + { + self::assertSame('Y', self::$element->canonical(' y ')); + self::assertSame('Y', self::$element->canonical('YES')); + self::assertSame('N', self::$element->canonical('NO')); + } +} diff --git a/tests/app/Elements/HeredisFILTest.php b/tests/app/Elements/HeredisFILTest.php new file mode 100644 index 00000000000..ed804aff4c3 --- /dev/null +++ b/tests/app/Elements/HeredisFILTest.php @@ -0,0 +1,39 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(HeredisFIL::class)] +class HeredisFILTest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new HeredisFIL('label'); + } + + public function testValues(): void + { + self::assertArrayHasKey('RECOGNIZED_CHILD', self::$element->values()); + } +} diff --git a/tests/app/Elements/HeredisFNATest.php b/tests/app/Elements/HeredisFNATest.php new file mode 100644 index 00000000000..6d5f0000a33 --- /dev/null +++ b/tests/app/Elements/HeredisFNATest.php @@ -0,0 +1,39 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(HeredisFNA::class)] +class HeredisFNATest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new HeredisFNA('label'); + } + + public function testValues(): void + { + self::assertArrayHasKey('IN_PROGRESS', self::$element->values()); + } +} diff --git a/tests/app/Elements/HeredisQualEvidTest.php b/tests/app/Elements/HeredisQualEvidTest.php new file mode 100644 index 00000000000..3f2c6b3a50f --- /dev/null +++ b/tests/app/Elements/HeredisQualEvidTest.php @@ -0,0 +1,39 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(HeredisQualEvid::class)] +class HeredisQualEvidTest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new HeredisQualEvid('label'); + } + + public function testValues(): void + { + self::assertArrayHasKey('N', self::$element->values()); + } +} diff --git a/tests/app/Elements/HeredisQualInfoTest.php b/tests/app/Elements/HeredisQualInfoTest.php new file mode 100644 index 00000000000..b14f56193b6 --- /dev/null +++ b/tests/app/Elements/HeredisQualInfoTest.php @@ -0,0 +1,39 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(HeredisQualInfo::class)] +class HeredisQualInfoTest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new HeredisQualInfo('label'); + } + + public function testValues(): void + { + self::assertArrayHasKey('S', self::$element->values()); + } +} diff --git a/tests/app/Elements/HeredisQualSourTest.php b/tests/app/Elements/HeredisQualSourTest.php new file mode 100644 index 00000000000..857726c92be --- /dev/null +++ b/tests/app/Elements/HeredisQualSourTest.php @@ -0,0 +1,39 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(HeredisQualSour::class)] +class HeredisQualSourTest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new HeredisQualSour('label'); + } + + public function testValues(): void + { + self::assertArrayHasKey('D', self::$element->values()); + } +} diff --git a/tests/app/Elements/HeredisRechElementTest.php b/tests/app/Elements/HeredisRechElementTest.php new file mode 100644 index 00000000000..5883b1af3a0 --- /dev/null +++ b/tests/app/Elements/HeredisRechElementTest.php @@ -0,0 +1,34 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(HeredisRechElement::class)] +class HeredisRechElementTest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new HeredisRechElement('label'); + } +} diff --git a/tests/app/Elements/HeredisUSTTest.php b/tests/app/Elements/HeredisUSTTest.php new file mode 100644 index 00000000000..b8e1cc0f18d --- /dev/null +++ b/tests/app/Elements/HeredisUSTTest.php @@ -0,0 +1,39 @@ +. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Elements; + +use PHPUnit\Framework\Attributes\CoversClass; + +#[CoversClass(AbstractElement::class)] +#[CoversClass(HeredisUST::class)] +class HeredisUSTTest extends AbstractElementTestCase +{ + public function setUp(): void + { + parent::setUp(); + + self::$element = new HeredisUST('label'); + } + + public function testValues(): void + { + self::assertArrayHasKey('MARRIED', self::$element->values()); + } +} From 4c6c4acb891718dfba97751676d15c6409b4b7ee Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 25 Jul 2025 14:00:53 +0200 Subject: [PATCH 12/20] codecov: increased test coverage --- tests/app/Elements/HeredisRechElementTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/app/Elements/HeredisRechElementTest.php b/tests/app/Elements/HeredisRechElementTest.php index 5883b1af3a0..f8d813b4ecf 100644 --- a/tests/app/Elements/HeredisRechElementTest.php +++ b/tests/app/Elements/HeredisRechElementTest.php @@ -31,4 +31,9 @@ public function setUp(): void self::$element = new HeredisRechElement('label'); } + + public function testCollapse(): void + { + self::assertTrue(self::$element->collapseChildren()); + } } From 04cee1947d83b2eae4381a06528b14e8ccd6647c Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 25 Jul 2025 14:29:21 +0200 Subject: [PATCH 13/20] fixed phpstan issue in HeredisTest.php --- tests/app/CustomTags/HeredisTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/CustomTags/HeredisTest.php b/tests/app/CustomTags/HeredisTest.php index 6375ba8bae1..61303944574 100644 --- a/tests/app/CustomTags/HeredisTest.php +++ b/tests/app/CustomTags/HeredisTest.php @@ -33,7 +33,7 @@ public function testClass(): void public function testHeredis(): void { $heredis = new Heredis(); - self::assertIsString($heredis->name()); + self::assertSame('Heredis', $heredis->name()); self::assertArrayHasKey('HEAD:_GUID', $heredis->tags()); self::assertArrayHasKey('SOUR:_CREA', $heredis->tags()); } From 52f3010b8e0979f1410f6571de63cf2abac313ea Mon Sep 17 00:00:00 2001 From: BertKoor Date: Wed, 31 Dec 2025 10:33:46 +0100 Subject: [PATCH 14/20] translation context added for Heredis tag INDI:_FIL --- app/Elements/HeredisFIL.php | 59 ++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/app/Elements/HeredisFIL.php b/app/Elements/HeredisFIL.php index cf1908ed78a..9df64605f08 100644 --- a/app/Elements/HeredisFIL.php +++ b/app/Elements/HeredisFIL.php @@ -26,23 +26,60 @@ */ class HeredisFIL extends AbstractElement { + + private const string VALUE_LEGITIMATE_CHILD = 'LEGITIMATE_CHILD'; + private const string VALUE_NATURAL_CHILD = 'NATURAL_CHILD'; + private const string VALUE_RECOGNIZED_CHILD = 'RECOGNIZED_CHILD'; + private const string VALUE_LEGITIMIZED_CHILD = 'LEGITIMIZED_CHILD'; + private const string VALUE_CHILD_FOUND = 'CHILD_FOUND'; + private const string VALUE_ADOPTED_CHILD = 'ADOPTED_CHILD'; + private const string VALUE_ADULTEROUS_CHILD = 'ADULTEROUS_CHILD'; + private const string VALUE_STILLBORN_CHILD = 'STILLBORN_CHILD'; + private const string VALUE_RELATIONSHIP_UNKNOWN = 'RELATIONSHIP_UNKNOW'; + /** * A list of controlled values for this element * * @return array */ - public function values(): array + public function values(string $sex = 'U'): array { - return [ - 'LEGITIMATE_CHILD' => I18N::translate('Legitimate'), - 'NATURAL_CHILD' => I18N::translate('Natural'), - 'RECOGNIZED_CHILD' => I18N::translate('Legally recognised'), - 'LEGITIMIZED_CHILD' => I18N::translate('Legitimated'), - 'CHILD_FOUND' => I18N::translate('Foundling'), - 'ADOPTED_CHILD' => I18N::translate('Adopted'), - 'ADULTEROUS_CHILD' => I18N::translate('Illegitimate'), - 'STILLBORN_CHILD' => I18N::translate('Stillborn'), - 'RELATIONSHIP_UNKNOW' => I18N::translate('Unknown'), + $values = [ + 'M' => [ + self::VALUE_LEGITIMATE_CHILD => I18N::translate('Legitimate'), + self::VALUE_NATURAL_CHILD => I18N::translate('Natural'), + self::VALUE_RECOGNIZED_CHILD => I18N::translate('Legally recognised'), + self::VALUE_LEGITIMIZED_CHILD => I18N::translate('Legitimated'), + self::VALUE_CHILD_FOUND => I18N::translate('Foundling'), + self::VALUE_ADOPTED_CHILD => I18N::translateContext('Male pedigree', 'Adopted'), + self::VALUE_ADULTEROUS_CHILD => I18N::translate('Illegitimate'), + self::VALUE_STILLBORN_CHILD => I18N::translate('stillborn'), + self::VALUE_RELATIONSHIP_UNKNOWN => I18N::translate('Unknown'), + ], + 'F' => [ + self::VALUE_LEGITIMATE_CHILD => I18N::translate('Legitimate'), + self::VALUE_NATURAL_CHILD => I18N::translate('Natural'), + self::VALUE_RECOGNIZED_CHILD => I18N::translate('Legally recognised'), + self::VALUE_LEGITIMIZED_CHILD => I18N::translate('Legitimated'), + self::VALUE_CHILD_FOUND => I18N::translate('Foundling'), + self::VALUE_ADOPTED_CHILD => I18N::translateContext('Female pedigree', 'Adopted'), + self::VALUE_ADULTEROUS_CHILD => I18N::translate('Illegitimate'), + self::VALUE_STILLBORN_CHILD => I18N::translate('stillborn'), + self::VALUE_RELATIONSHIP_UNKNOWN => I18N::translate('Unknown'), + ], + 'U' => [ + self::VALUE_LEGITIMATE_CHILD => I18N::translate('Legitimate'), + self::VALUE_NATURAL_CHILD => I18N::translate('Natural'), + self::VALUE_RECOGNIZED_CHILD => I18N::translate('Legally recognised'), + self::VALUE_LEGITIMIZED_CHILD => I18N::translate('Legitimated'), + self::VALUE_CHILD_FOUND => I18N::translate('Foundling'), + self::VALUE_ADOPTED_CHILD => I18N::translateContext('Pedigree', 'Adopted'), + self::VALUE_ADULTEROUS_CHILD => I18N::translate('Illegitimate'), + self::VALUE_STILLBORN_CHILD => I18N::translate('stillborn'), + self::VALUE_RELATIONSHIP_UNKNOWN => I18N::translate('Unknown'), + ], ]; + + return $values[$sex] ?? $values['U']; } } From a2aa17d4570c316cb65fbaeb95bff5142ae64c37 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Wed, 31 Dec 2025 10:49:01 +0100 Subject: [PATCH 15/20] removed param $sex on values(), seems never used --- app/Elements/HeredisFIL.php | 59 +++++++------------------------------ 1 file changed, 11 insertions(+), 48 deletions(-) diff --git a/app/Elements/HeredisFIL.php b/app/Elements/HeredisFIL.php index 9df64605f08..388a3de3067 100644 --- a/app/Elements/HeredisFIL.php +++ b/app/Elements/HeredisFIL.php @@ -26,60 +26,23 @@ */ class HeredisFIL extends AbstractElement { - - private const string VALUE_LEGITIMATE_CHILD = 'LEGITIMATE_CHILD'; - private const string VALUE_NATURAL_CHILD = 'NATURAL_CHILD'; - private const string VALUE_RECOGNIZED_CHILD = 'RECOGNIZED_CHILD'; - private const string VALUE_LEGITIMIZED_CHILD = 'LEGITIMIZED_CHILD'; - private const string VALUE_CHILD_FOUND = 'CHILD_FOUND'; - private const string VALUE_ADOPTED_CHILD = 'ADOPTED_CHILD'; - private const string VALUE_ADULTEROUS_CHILD = 'ADULTEROUS_CHILD'; - private const string VALUE_STILLBORN_CHILD = 'STILLBORN_CHILD'; - private const string VALUE_RELATIONSHIP_UNKNOWN = 'RELATIONSHIP_UNKNOW'; - /** * A list of controlled values for this element * * @return array */ - public function values(string $sex = 'U'): array + public function values(): array { - $values = [ - 'M' => [ - self::VALUE_LEGITIMATE_CHILD => I18N::translate('Legitimate'), - self::VALUE_NATURAL_CHILD => I18N::translate('Natural'), - self::VALUE_RECOGNIZED_CHILD => I18N::translate('Legally recognised'), - self::VALUE_LEGITIMIZED_CHILD => I18N::translate('Legitimated'), - self::VALUE_CHILD_FOUND => I18N::translate('Foundling'), - self::VALUE_ADOPTED_CHILD => I18N::translateContext('Male pedigree', 'Adopted'), - self::VALUE_ADULTEROUS_CHILD => I18N::translate('Illegitimate'), - self::VALUE_STILLBORN_CHILD => I18N::translate('stillborn'), - self::VALUE_RELATIONSHIP_UNKNOWN => I18N::translate('Unknown'), - ], - 'F' => [ - self::VALUE_LEGITIMATE_CHILD => I18N::translate('Legitimate'), - self::VALUE_NATURAL_CHILD => I18N::translate('Natural'), - self::VALUE_RECOGNIZED_CHILD => I18N::translate('Legally recognised'), - self::VALUE_LEGITIMIZED_CHILD => I18N::translate('Legitimated'), - self::VALUE_CHILD_FOUND => I18N::translate('Foundling'), - self::VALUE_ADOPTED_CHILD => I18N::translateContext('Female pedigree', 'Adopted'), - self::VALUE_ADULTEROUS_CHILD => I18N::translate('Illegitimate'), - self::VALUE_STILLBORN_CHILD => I18N::translate('stillborn'), - self::VALUE_RELATIONSHIP_UNKNOWN => I18N::translate('Unknown'), - ], - 'U' => [ - self::VALUE_LEGITIMATE_CHILD => I18N::translate('Legitimate'), - self::VALUE_NATURAL_CHILD => I18N::translate('Natural'), - self::VALUE_RECOGNIZED_CHILD => I18N::translate('Legally recognised'), - self::VALUE_LEGITIMIZED_CHILD => I18N::translate('Legitimated'), - self::VALUE_CHILD_FOUND => I18N::translate('Foundling'), - self::VALUE_ADOPTED_CHILD => I18N::translateContext('Pedigree', 'Adopted'), - self::VALUE_ADULTEROUS_CHILD => I18N::translate('Illegitimate'), - self::VALUE_STILLBORN_CHILD => I18N::translate('stillborn'), - self::VALUE_RELATIONSHIP_UNKNOWN => I18N::translate('Unknown'), - ], + return [ + 'LEGITIMATE_CHILD' => I18N::translate('Legitimate'), + 'NATURAL_CHILD' => I18N::translate('Natural'), + 'RECOGNIZED_CHILD' => I18N::translate('Legally recognised'), + 'LEGITIMIZED_CHILD' => I18N::translate('Legitimated'), + 'CHILD_FOUND' => I18N::translate('Foundling'), + 'ADOPTED_CHILD' => I18N::translateContext('Pedigree', 'Adopted'), + 'ADULTEROUS_CHILD' => I18N::translate('Illegitimate'), + 'STILLBORN_CHILD' => I18N::translate('stillborn'), + 'RELATIONSHIP_UNKNOW' => I18N::translate('Unknown'), ]; - - return $values[$sex] ?? $values['U']; } } From d88df175d7f6bcba885342909b2eabc34bf4d7eb Mon Sep 17 00:00:00 2001 From: BertKoor Date: Wed, 31 Dec 2025 10:55:28 +0100 Subject: [PATCH 16/20] added translation context --- app/Elements/HeredisUST.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Elements/HeredisUST.php b/app/Elements/HeredisUST.php index 545895a2e88..9fefdee142a 100644 --- a/app/Elements/HeredisUST.php +++ b/app/Elements/HeredisUST.php @@ -34,9 +34,9 @@ class HeredisUST extends AbstractElement public function values(): array { return [ - 'MARRIED' => I18N::translate('Marriage'), + 'MARRIED' => I18N::translateContext('FAM:_UST','Marriage'), 'ENGAGEMENT' => I18N::translate('Engaged'), - 'SEPARATED' => I18N::translate('Separation'), + 'SEPARATED' => I18N::translateContext('FAM:_UST','Separation'), 'DIVORCED' => I18N::translate('Divorce'), 'COMMON_LAW' => I18N::translate('Other type of marriage'), 'COHABITATION' => I18N::translate('Cohabitee'), From 5884f9f51cf2157c084c81f9a060a9cc9bdaed0c Mon Sep 17 00:00:00 2001 From: BertKoor Date: Wed, 11 Feb 2026 15:06:23 +0100 Subject: [PATCH 17/20] Heredis tag _FNA also occurs in Family records --- app/CustomTags/Heredis.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/CustomTags/Heredis.php b/app/CustomTags/Heredis.php index 9d017cd0a8f..06666435737 100644 --- a/app/CustomTags/Heredis.php +++ b/app/CustomTags/Heredis.php @@ -88,6 +88,7 @@ public function tags(): array 'FAM:*:SOUR:_QUAL:_SOUR' => new HeredisQualSour(I18N::translate('Quality of the source')), 'FAM:*:SOUR:_QUAL:_INFO' => new HeredisQualInfo(I18N::translate('Quality of the information')), 'FAM:*:SOUR:_QUAL:_EVID' => new HeredisQualEvid(I18N::translate('Quality of the evidence')), + 'FAM:*:_FNA' => new HeredisFNA(I18N::translate('Research status')), 'FAM:*:_RECH' => new EmptyElement(I18N::translate('Research data')), 'FAM:*:_RECH:_PROJ' => new CustomElement(I18N::translate('Research project')), 'FAM:*:_RECH:TYPE' => new CustomElement(I18N::translate('Document')), From ce2b9aa305d97c8b4ac1e00e7bd39a646b75af3f Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 13 Feb 2026 10:44:15 +0100 Subject: [PATCH 18/20] Heredis tag HEAD:_GUID is a regular UID, not PAF format --- app/CustomTags/Heredis.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/CustomTags/Heredis.php b/app/CustomTags/Heredis.php index 06666435737..f323571106a 100644 --- a/app/CustomTags/Heredis.php +++ b/app/CustomTags/Heredis.php @@ -39,13 +39,13 @@ use Fisharebest\Webtrees\Elements\HeredisRechElement; use Fisharebest\Webtrees\Elements\HeredisUST; use Fisharebest\Webtrees\Elements\NoteStructure; -use Fisharebest\Webtrees\Elements\PafUid; use Fisharebest\Webtrees\Elements\PlaceLatitude; use Fisharebest\Webtrees\Elements\PlaceLongtitude; use Fisharebest\Webtrees\Elements\PlaceName; use Fisharebest\Webtrees\Elements\RoleInEvent; use Fisharebest\Webtrees\Elements\SourceCallNumber; use Fisharebest\Webtrees\Elements\TimeValue; +use Fisharebest\Webtrees\Elements\Uid; use Fisharebest\Webtrees\Elements\UserReferenceNumber; use Fisharebest\Webtrees\I18N; @@ -77,7 +77,7 @@ public function name(): string public function tags(): array { return [ - 'HEAD:_GUID' => new PafUid(I18N::translate('File identifier')), + 'HEAD:_GUID' => new Uid(I18N::translate('File identifier')), 'FAM:_CREA' => new Creation(I18N::translate('Created at')), 'FAM:_UST' => new HeredisUST(I18N::translate('Union type')), 'FAM:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), From eb6d1e5eb708727632b5284a7cf0d6c2bbfab0f4 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 13 Feb 2026 11:11:02 +0100 Subject: [PATCH 19/20] added Heredis tags HEAL & PAGE --- app/CustomTags/Heredis.php | 2 ++ app/Module/IndividualMetadataModule.php | 1 + 2 files changed, 3 insertions(+) diff --git a/app/CustomTags/Heredis.php b/app/CustomTags/Heredis.php index 0df50a3f41e..482fb3c6371 100644 --- a/app/CustomTags/Heredis.php +++ b/app/CustomTags/Heredis.php @@ -110,6 +110,8 @@ public function tags(): array 'INDI:ASSO:_ROLE' => new RoleInEvent(I18N::translate('Role')), 'INDI:ASSO:_TITL' => new CustomElement(I18N::translate('Title')), 'INDI:ASSO:_TYPE' => new CustomElement(I18N::translate('Type')), + 'INDI:HEAL' => new CustomElement(I18N::translate('Health')), + 'INDI:PAGE' => new CustomElement(I18N::translate('Reference number')), 'INDI:*:DATE:_TIME' => new TimeValue(I18N::translate('Time')), 'INDI:*:PLAC:_SUBMAP' => new Coordinates(I18N::translate('Geolocation of subdivisions')), 'INDI:*:PLAC:_SUBMAP:LATI' => new PlaceLatitude(I18N::translate('Latitude of subdivision')), diff --git a/app/Module/IndividualMetadataModule.php b/app/Module/IndividualMetadataModule.php index 5b7c52a0afd..6cf20f4898c 100644 --- a/app/Module/IndividualMetadataModule.php +++ b/app/Module/IndividualMetadataModule.php @@ -41,6 +41,7 @@ class IndividualMetadataModule extends AbstractModule implements ModuleSidebarIn 'CHAN', 'DESI', 'IDNO', + 'PAGE', 'REFN', 'RESN', 'RFN', From 5dd0e765d41fb991b689f45c378aa3830a8fa5b9 Mon Sep 17 00:00:00 2001 From: BertKoor Date: Fri, 13 Feb 2026 11:38:24 +0100 Subject: [PATCH 20/20] hide tag FAM:_CREA on Individual facts & events --- app/Module/IndividualFactsTabModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Module/IndividualFactsTabModule.php b/app/Module/IndividualFactsTabModule.php index ee289428584..1bd2541ac6b 100644 --- a/app/Module/IndividualFactsTabModule.php +++ b/app/Module/IndividualFactsTabModule.php @@ -115,7 +115,7 @@ public function getTabContent(Individual $individual): string ->flatten(); // Don't show family meta-data tags - $exclude_facts = new Collection(['FAM:CHAN', 'FAM:_UID', 'FAM:UID', 'FAM:SUBM']); + $exclude_facts = new Collection(['FAM:CHAN', 'FAM:_UID', 'FAM:UID', 'FAM:SUBM', 'FAM:_CREA']); // Don't show tags that are shown in tabs or sidebars $exclude_facts = $exclude_facts->merge($sidebar_facts)->merge($tab_facts);