diff options
45 files changed, 1978 insertions, 811 deletions
diff --git a/app/Contracts/ElementInterface.php b/app/Contracts/ElementInterface.php index d4bd3283d0..145e3a50f4 100644 --- a/app/Contracts/ElementInterface.php +++ b/app/Contracts/ElementInterface.php @@ -87,11 +87,11 @@ interface ElementInterface * * @param string $subtag * @param string $repeat - * @param string $after + * @param string $before * * @return void */ - public function subtag(string $subtag, string $repeat = '', string $after = ''): void; + public function subtag(string $subtag, string $repeat, string $before): void; /** * @return array<string,string> diff --git a/app/Elements/AbstractElement.php b/app/Elements/AbstractElement.php index 186049fa09..1886fa85bc 100644 --- a/app/Elements/AbstractElement.php +++ b/app/Elements/AbstractElement.php @@ -26,11 +26,11 @@ use Fisharebest\Webtrees\Tree; use function array_key_exists; use function array_map; -use function array_search; use function e; use function is_numeric; use function preg_match; -use function strpos; +use function str_contains; +use function strip_tags; use function trim; use function view; @@ -48,11 +48,11 @@ abstract class AbstractElement implements ElementInterface // Which child elements can appear under this element. protected const SUBTAGS = []; - /** @var string A label to describe this element */ - private $label; + // A label to describe this element + private string $label; - /** @var array<string,string> */ - private $subtags; + /** @var array<string,string> Subtags of this element */ + private array $subtags; /** * AbstractGedcomElement constructor. @@ -77,7 +77,7 @@ abstract class AbstractElement implements ElementInterface { $value = strtr($value, ["\t" => ' ', "\r" => ' ', "\n" => ' ']); - while (strpos($value, ' ') !== false) { + while (str_contains($value, ' ')) { $value = strtr($value, [' ' => ' ']); } @@ -119,7 +119,7 @@ abstract class AbstractElement implements ElementInterface } // We may use markup to display values, but not when editing them. - $values = array_map('strip_tags', $values); + $values = array_map(fn(string $x): string => strip_tags($x), $values); return view('components/select', [ 'id' => $id, @@ -214,25 +214,24 @@ abstract class AbstractElement implements ElementInterface * * @param string $subtag * @param string $repeat - * @param string $after + * @param string $before * * @return void */ - public function subtag(string $subtag, string $repeat = '', string $after = ''): void + public function subtag(string $subtag, string $repeat, string $before): void { if ($repeat === '') { unset($this->subtags[$subtag]); - } elseif ($after === '' || ($this->subtags[$subtag] ?? null) === null) { + } elseif ($before === '' || ($this->subtags[$before] ?? null) === null) { $this->subtags[$subtag] = $repeat; } else { $tmp = []; foreach ($this->subtags as $key => $value) { - $tmp[$key] = $value; - - if ($key === $after) { - $tmp[] = $repeat; + if ($key === $before) { + $tmp[$key] = $repeat; } + $tmp[$key] = $value; } $this->subtags = $tmp; diff --git a/app/Elements/Change.php b/app/Elements/Change.php index a7889d6d89..955f605c4e 100644 --- a/app/Elements/Change.php +++ b/app/Elements/Change.php @@ -24,4 +24,8 @@ namespace Fisharebest\Webtrees\Elements; */ class Change extends EmptyElement { + protected const SUBTAGS = [ + 'DATE' => '1:1', + 'NOTE' => '0:M', + ]; } diff --git a/app/Elements/ChangeDate.php b/app/Elements/ChangeDate.php index 767e8e063f..63d16edd8c 100644 --- a/app/Elements/ChangeDate.php +++ b/app/Elements/ChangeDate.php @@ -29,6 +29,10 @@ use Fisharebest\Webtrees\Tree; */ class ChangeDate extends AbstractElement { + protected const SUBTAGS = [ + 'TIME' => '1:1', + ]; + /** * Display the value of this type of element. * diff --git a/app/Elements/FamilyRecord.php b/app/Elements/FamilyRecord.php index 8a0ce7c55f..9136edfb12 100644 --- a/app/Elements/FamilyRecord.php +++ b/app/Elements/FamilyRecord.php @@ -26,6 +26,7 @@ class FamilyRecord extends AbstractElement { protected const SUBTAGS = [ 'MARR' => '0:1', + 'RESN' => '0:1', 'CHAN' => '0:1', ]; } diff --git a/app/Elements/FamilyStatusText.php b/app/Elements/FamilyStatusText.php index e230e7e0ce..903cce60e6 100644 --- a/app/Elements/FamilyStatusText.php +++ b/app/Elements/FamilyStatusText.php @@ -33,6 +33,13 @@ use function strtoupper; */ class FamilyStatusText extends AbstractElement { + protected const SUBTAGS = [ + 'DATE' => '0:1', + 'PLAC' => '0:1', + 'NOTE' => '0:M', + 'SOUR' => '0:M', + ]; + /** * Convert a value to a canonical form. * diff --git a/app/Elements/IndividualRecord.php b/app/Elements/IndividualRecord.php index 036a69d65c..db2693a9c9 100644 --- a/app/Elements/IndividualRecord.php +++ b/app/Elements/IndividualRecord.php @@ -28,6 +28,7 @@ class IndividualRecord extends AbstractElement 'SEX' => '1:1', 'BIRT' => '0:1', 'DEAT' => '0:1', + 'RESN' => '0:1', 'CHAN' => '0:1', ]; } diff --git a/app/Elements/MediaRecord.php b/app/Elements/MediaRecord.php index ec597bcf04..22eff9fea3 100644 --- a/app/Elements/MediaRecord.php +++ b/app/Elements/MediaRecord.php @@ -30,7 +30,7 @@ class MediaRecord extends AbstractElement 'RIN' => '0:1', 'NOTE' => '0:M', 'SOUR' => '0:M', + 'RESN' => '0:1', 'CHAN' => '0:1', - 'RESN' => '0:1', /* *** webtrees extension */ ]; } diff --git a/app/Elements/NamePersonal.php b/app/Elements/NamePersonal.php index 31af63c8e0..deda8f934b 100644 --- a/app/Elements/NamePersonal.php +++ b/app/Elements/NamePersonal.php @@ -24,6 +24,7 @@ use Fisharebest\Webtrees\SurnameTradition; use Fisharebest\Webtrees\Tree; use function e; +use function in_array; use function view; /** @@ -61,6 +62,27 @@ class NamePersonal extends AbstractElement 'SURN' => '0:1', 'NSFX' => '0:1', 'NICK' => '0:1', + 'NOTE' => '0:M', + 'SOUR' => '0:M', + 'FONE' => '0:M', + 'ROMN' => '0:M', + ]; + + // For some languages, we want to show the surname field first. + protected const SURNAME_FIRST_LANGUAGES = ['hu', 'jp', 'ko', 'zh-Hans', 'zh-Hant']; + + protected const SUBTAGS_SURNAME_FIRST = [ + 'TYPE' => '0:1', + 'NPFX' => '0:1', + 'SPFX' => '0:1', + 'SURN' => '0:1', + 'GIVN' => '0:1', + 'NSFX' => '0:1', + 'NICK' => '0:1', + 'NOTE' => '0:M', + 'SOUR' => '0:M', + 'FONE' => '0:M', + 'ROMN' => '0:M', ]; /** @@ -107,37 +129,10 @@ class NamePersonal extends AbstractElement */ public function subtags(): array { - $language = I18N::languageTag(); - - switch ($language) { - case 'hu': - case 'jp': - case 'ko': - case 'zh-Hans': - case 'zh-Hant': - $subtags = [ - 'TYPE' => '0:1', - 'NPFX' => '0:1', - 'SPFX' => '0:1', - 'SURN' => '0:1', - 'GIVN' => '0:1', - 'NSFX' => '0:1', - 'NICK' => '0:1', - ]; - break; - default: - $subtags = [ - 'TYPE' => '0:1', - 'NPFX' => '0:1', - 'GIVN' => '0:1', - 'SPFX' => '0:1', - 'SURN' => '0:1', - 'NSFX' => '0:1', - 'NICK' => '0:1', - ]; - break; + if (in_array(I18N::languageTag(), static::SURNAME_FIRST_LANGUAGES, true)) { + return static::SUBTAGS_SURNAME_FIRST; } - return $subtags; + return static::SUBTAGS; } } diff --git a/app/Elements/NamePhoneticVariation.php b/app/Elements/NamePhoneticVariation.php index cdf4da01d8..6e9c2bf042 100644 --- a/app/Elements/NamePhoneticVariation.php +++ b/app/Elements/NamePhoneticVariation.php @@ -29,7 +29,15 @@ namespace Fisharebest\Webtrees\Elements; */ class NamePhoneticVariation extends AbstractElement { - protected const SUBTAGS = ['NPFX', 'GIVN', 'SPFX','SURN', 'NSFX', 'NICK', 'TYPE']; - protected const MAXIMUM_LENGTH = 120; + + protected const SUBTAGS = [ + 'TYPE' => '0:1', + 'NPFX' => '0:1', + 'GIVN' => '0:1', + 'SPFX' => '0:1', + 'SURN' => '0:1', + 'NSFX' => '0:1', + 'NICK' => '0:1', + ]; } diff --git a/app/Elements/NameRomanizedVariation.php b/app/Elements/NameRomanizedVariation.php index ffec3581ff..85764f4458 100644 --- a/app/Elements/NameRomanizedVariation.php +++ b/app/Elements/NameRomanizedVariation.php @@ -35,10 +35,18 @@ use function view; */ class NameRomanizedVariation extends AbstractElement { - protected const SUBTAGS = ['NPFX', 'GIVN', 'SPFX','SURN', 'NSFX', 'NICK', 'TYPE']; - protected const MAXIMUM_LENGTH = 120; + protected const SUBTAGS = [ + 'TYPE' => '0:1', + 'NPFX' => '0:1', + 'GIVN' => '0:1', + 'SPFX' => '0:1', + 'SURN' => '0:1', + 'NSFX' => '0:1', + 'NICK' => '0:1', + ]; + /** * An edit control for this data. * diff --git a/app/Elements/NoteRecord.php b/app/Elements/NoteRecord.php index e9aec25d27..3ad36123a4 100644 --- a/app/Elements/NoteRecord.php +++ b/app/Elements/NoteRecord.php @@ -29,5 +29,6 @@ class NoteRecord extends AbstractElement 'REFN' => '0:1', 'RIN' => '0:1', 'SOUR' => '0:M', + 'CHAN' => '0:1', ]; } diff --git a/app/Elements/RepositoryRecord.php b/app/Elements/RepositoryRecord.php index 4f073ee648..051ec0acff 100644 --- a/app/Elements/RepositoryRecord.php +++ b/app/Elements/RepositoryRecord.php @@ -33,5 +33,6 @@ class RepositoryRecord extends AbstractElement 'NOTE' => '0:M', 'REFN' => '0:1', 'RIN' => '0:1', + 'CHAN' => '0:1', ]; } diff --git a/app/Elements/SourceRecord.php b/app/Elements/SourceRecord.php index b71c0ecd77..2512532a37 100644 --- a/app/Elements/SourceRecord.php +++ b/app/Elements/SourceRecord.php @@ -36,5 +36,6 @@ class SourceRecord extends AbstractElement 'DATA' => '0:1', 'REFN' => '0:1', 'RIN' => '0:1', + 'CHAN' => '0:1', ]; } diff --git a/app/Elements/XrefRepository.php b/app/Elements/XrefRepository.php index 026a0cf651..ce92a63f8c 100644 --- a/app/Elements/XrefRepository.php +++ b/app/Elements/XrefRepository.php @@ -36,7 +36,8 @@ use function view; class XrefRepository extends AbstractXrefElement { protected const SUBTAGS = [ - 'CALN' => '0:1' + 'CALN' => '0:1', + 'NOTE' => '0:M', ]; /** diff --git a/app/Factories/ElementFactory.php b/app/Factories/ElementFactory.php index 5f7abbd16d..178c9b70d7 100644 --- a/app/Factories/ElementFactory.php +++ b/app/Factories/ElementFactory.php @@ -62,9 +62,6 @@ use Fisharebest\Webtrees\Elements\CopyrightSourceData; use Fisharebest\Webtrees\Elements\CountOfChildren; use Fisharebest\Webtrees\Elements\CountOfMarriages; use Fisharebest\Webtrees\Elements\Cremation; -use Fisharebest\Webtrees\Elements\CustomElement; -use Fisharebest\Webtrees\Elements\CustomEvent; -use Fisharebest\Webtrees\Elements\CustomFact; use Fisharebest\Webtrees\Elements\DateLdsOrd; use Fisharebest\Webtrees\Elements\DateValue; use Fisharebest\Webtrees\Elements\Death; @@ -81,18 +78,14 @@ use Fisharebest\Webtrees\Elements\EventOrFactClassification; use Fisharebest\Webtrees\Elements\EventsRecorded; use Fisharebest\Webtrees\Elements\EventTypeCitedFrom; use Fisharebest\Webtrees\Elements\FamilyRecord; -use Fisharebest\Webtrees\Elements\FamilySearchFamilyTreeId; -use Fisharebest\Webtrees\Elements\FamilyStatusText; use Fisharebest\Webtrees\Elements\FileName; use Fisharebest\Webtrees\Elements\FirstCommunion; use Fisharebest\Webtrees\Elements\Form; use Fisharebest\Webtrees\Elements\GedcomElement; use Fisharebest\Webtrees\Elements\GenerationsOfAncestors; use Fisharebest\Webtrees\Elements\GenerationsOfDescendants; -use Fisharebest\Webtrees\Elements\GovIdentifier; use Fisharebest\Webtrees\Elements\Graduation; use Fisharebest\Webtrees\Elements\HeaderRecord; -use Fisharebest\Webtrees\Elements\HierarchicalRelationship; use Fisharebest\Webtrees\Elements\Immigration; use Fisharebest\Webtrees\Elements\IndividualRecord; use Fisharebest\Webtrees\Elements\LanguageId; @@ -105,8 +98,6 @@ use Fisharebest\Webtrees\Elements\LdsEndowment; use Fisharebest\Webtrees\Elements\LdsEndowmentDateStatus; use Fisharebest\Webtrees\Elements\LdsSpouseSealing; use Fisharebest\Webtrees\Elements\LdsSpouseSealingDateStatus; -use Fisharebest\Webtrees\Elements\LocationRecord; -use Fisharebest\Webtrees\Elements\MaidenheadLocator; use Fisharebest\Webtrees\Elements\Marriage; use Fisharebest\Webtrees\Elements\MarriageBanns; use Fisharebest\Webtrees\Elements\MarriageContract; @@ -140,7 +131,6 @@ use Fisharebest\Webtrees\Elements\NoteStructure; use Fisharebest\Webtrees\Elements\Occupation; use Fisharebest\Webtrees\Elements\OrdinanceProcessFlag; use Fisharebest\Webtrees\Elements\Ordination; -use Fisharebest\Webtrees\Elements\PafUid; use Fisharebest\Webtrees\Elements\PedigreeLinkageType; use Fisharebest\Webtrees\Elements\PermanentRecordFileNumber; use Fisharebest\Webtrees\Elements\PhoneNumber; @@ -160,10 +150,6 @@ use Fisharebest\Webtrees\Elements\ReceivingSystemName; use Fisharebest\Webtrees\Elements\RelationIsDescriptor; use Fisharebest\Webtrees\Elements\ReligiousAffiliation; use Fisharebest\Webtrees\Elements\RepositoryRecord; -use Fisharebest\Webtrees\Elements\ResearchTask; -use Fisharebest\Webtrees\Elements\ResearchTaskPriority; -use Fisharebest\Webtrees\Elements\ResearchTaskStatus; -use Fisharebest\Webtrees\Elements\ResearchTaskType; use Fisharebest\Webtrees\Elements\Residence; use Fisharebest\Webtrees\Elements\ResponsibleAgency; use Fisharebest\Webtrees\Elements\RestrictionNotice; @@ -172,7 +158,6 @@ use Fisharebest\Webtrees\Elements\RoleInEvent; use Fisharebest\Webtrees\Elements\RomanizedType; use Fisharebest\Webtrees\Elements\ScholasticAchievement; use Fisharebest\Webtrees\Elements\SexValue; -use Fisharebest\Webtrees\Elements\SexXValue; use Fisharebest\Webtrees\Elements\SocialSecurityNumber; use Fisharebest\Webtrees\Elements\SourceCallNumber; use Fisharebest\Webtrees\Elements\SourceData; @@ -195,13 +180,11 @@ use Fisharebest\Webtrees\Elements\UnknownElement; use Fisharebest\Webtrees\Elements\UserReferenceNumber; use Fisharebest\Webtrees\Elements\UserReferenceType; use Fisharebest\Webtrees\Elements\VersionNumber; -use Fisharebest\Webtrees\Elements\WebtreesUser; use Fisharebest\Webtrees\Elements\WhereWithinSource; use Fisharebest\Webtrees\Elements\Will; use Fisharebest\Webtrees\Elements\XrefAssociate; use Fisharebest\Webtrees\Elements\XrefFamily; use Fisharebest\Webtrees\Elements\XrefIndividual; -use Fisharebest\Webtrees\Elements\XrefLocation; use Fisharebest\Webtrees\Elements\XrefMedia; use Fisharebest\Webtrees\Elements\XrefRepository; use Fisharebest\Webtrees\Elements\XrefSource; @@ -243,698 +226,7 @@ class ElementFactory implements ElementFactoryInterface private function elements(): array { if ($this->elements === []) { - // Gedcom 5.5.1 $this->elements = $this->gedcom551(); - - // Aldfaer extensions - $this->register([ - 'FAM:MARR_CIVIL' => new CustomEvent(I18N::translate('Civil marriage')), - 'FAM:MARR_RELIGIOUS' => new CustomEvent(I18N::translate('Religious marriage')), - 'FAM:MARR_PARTNERS' => new CustomEvent(I18N::translate('Registered partnership')), - 'FAM:MARR_UNKNOWN' => new CustomEvent(I18N::translate('Marriage type unknown')), - ]); - - // Ancestry extensions - $this->register([ - 'INDI:*:SOUR:_APID' => new CustomElement(I18N::translate('Ancestry PID')), - 'INDI:_EMPLOY' => new CustomEvent(I18N::translate('Occupation')), - ]); - - // Brother’s Keeper extensions - $this->register([ - 'FAM:*:_EVN' => new CustomElement('Event number'), - 'FAM:CHIL:_FREL' => new CustomElement('Relationship to father'), - 'FAM:CHIL:_MREL' => new CustomElement('Relationship to mother'), - 'FAM:_COML' => new CustomEvent(I18N::translate('Common law marriage')), - 'FAM:_MARI' => new CustomEvent(I18N::translate('Marriage intention')), - 'FAM:_MBON' => new CustomEvent(I18N::translate('Marriage bond')), - 'FAM:_NMR' => new CustomEvent(I18N::translate('Not married'), ['NOTE' => '0:M', 'SOUR' => '0:M']), - 'FAM:_PRMN' => new CustomElement(I18N::translate('Permanent number')), - 'FAM:_SEPR' => new CustomEvent(I18N::translate('Separated')), - 'FAM:_TODO' => new CustomElement(I18N::translate('Research task')), - 'INDI:*:_EVN' => new CustomElement('Event number'), - 'INDI:NAME:_ADPN' => new NamePersonal(I18N::translate('Adopted name'), []), - 'INDI:NAME:_AKAN' => new NamePersonal(I18N::translate('Also known as'), []), - 'INDI:NAME:_BIRN' => new NamePersonal(I18N::translate('Birth name'), []), - 'INDI:NAME:_CALL' => new NamePersonal('Called name', []), - 'INDI:NAME:_CENN' => new NamePersonal('Census name', []), - 'INDI:NAME:_CURN' => new NamePersonal('Current name', []), - 'INDI:NAME:_FARN' => new NamePersonal(I18N::translate('Estate name'), []), - 'INDI:NAME:_FKAN' => new NamePersonal('Formal name', []), - 'INDI:NAME:_FRKA' => new NamePersonal('Formerly known as', []), - 'INDI:NAME:_GERN' => new NamePersonal('German name', []), - 'INDI:NAME:_HEBN' => new NamePersonal(I18N::translate('Hebrew name'), []), - 'INDI:NAME:_HNM' => new NamePersonal(I18N::translate('Hebrew name'), []), - 'INDI:NAME:_INDG' => new NamePersonal('Indigenous name', []), - 'INDI:NAME:_INDN' => new NamePersonal('Indian name', []), - 'INDI:NAME:_LNCH' => new NamePersonal('Legal name change', []), - 'INDI:NAME:_MARN' => new NamePersonal('Married name', []), - 'INDI:NAME:_MARNM' => new NamePersonal('Married name', []), - 'INDI:NAME:_OTHN' => new NamePersonal('Other name', []), - 'INDI:NAME:_RELN' => new NamePersonal('Religious name', []), - 'INDI:NAME:_SHON' => new NamePersonal('Short name', []), - 'INDI:NAME:_SLDN' => new NamePersonal('Soldier name', []), - 'INDI:_ADPF' => new CustomElement(I18N::translate('Adopted by father')), - 'INDI:_ADPM' => new CustomElement(I18N::translate('Adopted by mother')), - 'INDI:_BRTM' => new CustomEvent(I18N::translate('Brit milah')), - 'INDI:_BRTM:DATE' => new DateValue(I18N::translate('Date of brit milah')), - 'INDI:_BRTM:PLAC' => new PlaceName(I18N::translate('Place of brit milah')), - 'INDI:_EMAIL' => new AddressEmail(I18N::translate('Email address')), - 'INDI:_EYEC' => new CustomFact(I18N::translate('Eye color')), - 'INDI:_FRNL' => new CustomElement(I18N::translate('Funeral')), - 'INDI:_HAIR' => new CustomFact(I18N::translate('Hair color')), - 'INDI:_HEIG' => new CustomFact(I18N::translate('Height')), - 'INDI:_INTE' => new CustomElement(I18N::translate('Interment')), - 'INDI:_MEDC' => new CustomFact(I18N::translate('Medical')), - 'INDI:_MILT' => new CustomElement(I18N::translate('Military service')), - 'INDI:_NLIV' => new CustomFact(I18N::translate('Not living')), - 'INDI:_NMAR' => new CustomEvent(I18N::translate('Never married'), ['NOTE' => '0:M', 'SOUR' => '0:M']), - 'INDI:_PRMN' => new CustomElement(I18N::translate('Permanent number')), - 'INDI:_TODO' => new CustomElement(I18N::translate('Research task')), - 'INDI:_WEIG' => new CustomFact(I18N::translate('Weight')), - 'INDI:_YART' => new CustomEvent(I18N::translate('Yahrzeit')), - // 1 XXXX - // 2 _EVN ## - // 1 ASSO @Xnnn@ - // 2 RELA Witness at event _EVN ## - ]); - - // familysearch.org extensions - $this->register([ - 'INDI:_FSFTID' => /* I18N: familysearch.org */ new FamilySearchFamilyTreeId(I18N::translate('FamilySearch ID')), - ]); - - // Family Tree Builder extensions - $this->register([ - '*:_UPD' => new CustomElement(I18N::translate('Last change')), // e.g. "1 _UPD 14 APR 2012 00:14:10 GMT-5" - 'INDI:NAME:_AKA' => new NamePersonal(I18N::translate('Also known as'), []), - 'OBJE:_ALBUM' => new CustomElement(I18N::translate('Album')), // XREF to an album - 'OBJE:_DATE' => new DateValue(I18N::translate('Date')), - 'OBJE:_FILESIZE' => new CustomElement(I18N::translate('File size')), - 'OBJE:_PHOTO_RIN' => new CustomElement(I18N::translate('Photo')), - 'OBJE:_PLACE' => new PlaceName(I18N::translate('Place')), - '_ALBUM:_PHOTO' => new CustomElement(I18N::translate('Photo')), - '_ALBUM:_PHOTO:_PRIN' => new CustomElement(I18N::translate('Highlighted image')), - ]); - - // Family Tree Maker extensions - $this->register([ - 'FAM:CHIL:_FREL' => new CustomElement(I18N::translate('Relationship to father')), - 'FAM:CHIL:_MREL' => new CustomElement(I18N::translate('Relationship to mother')), - 'FAM:_DETS' => new CustomElement(I18N::translate('Death of one spouse')), - 'FAM:_FA1' => new CustomElement('Fact 1'), - 'FAM:_FA10' => new CustomElement('Fact 10'), - 'FAM:_FA11' => new CustomElement('Fact 11'), - 'FAM:_FA12' => new CustomElement('Fact 12'), - 'FAM:_FA13' => new CustomElement('Fact 13'), - 'FAM:_FA2' => new CustomElement('Fact 2'), - 'FAM:_FA3' => new CustomElement('Fact 3'), - 'FAM:_FA4' => new CustomElement('Fact 4'), - 'FAM:_FA5' => new CustomElement('Fact 5'), - 'FAM:_FA6' => new CustomElement('Fact 6'), - 'FAM:_FA7' => new CustomElement('Fact 7'), - 'FAM:_FA8' => new CustomElement('Fact 8'), - 'FAM:_FA9' => new CustomElement('Fact 9'), - 'FAM:_MEND' => new CustomElement(I18N::translate('Marriage ending status')), - 'FAM:_MSTAT' => new CustomElement(I18N::translate('Marriage beginning status')), - 'FAM:_SEPR' => new CustomElement(I18N::translate('Separation')), - 'HEAD:_SCHEMA' => new CustomElement('Schema'), - 'HEAD:_SCHEMA:FAM' => new CustomElement(I18N::translate('Family')), - 'HEAD:_SCHEMA:FAM:_FA*:LABL' => new CustomElement(I18N::translate('Label')), - 'HEAD:_SCHEMA:FAM:_FA1' => new CustomElement(I18N::translate('Fact 1')), - 'HEAD:_SCHEMA:FAM:_FA10' => new CustomElement(I18N::translate('Fact 10')), - 'HEAD:_SCHEMA:FAM:_FA11' => new CustomElement(I18N::translate('Fact 11')), - 'HEAD:_SCHEMA:FAM:_FA12' => new CustomElement(I18N::translate('Fact 12')), - 'HEAD:_SCHEMA:FAM:_FA13' => new CustomElement(I18N::translate('Fact 13')), - 'HEAD:_SCHEMA:FAM:_FA2' => new CustomElement(I18N::translate('Fact 2')), - 'HEAD:_SCHEMA:FAM:_FA3' => new CustomElement(I18N::translate('Fact 3')), - 'HEAD:_SCHEMA:FAM:_FA4' => new CustomElement(I18N::translate('Fact 4')), - 'HEAD:_SCHEMA:FAM:_FA5' => new CustomElement(I18N::translate('Fact 5')), - 'HEAD:_SCHEMA:FAM:_FA6' => new CustomElement(I18N::translate('Fact 6')), - 'HEAD:_SCHEMA:FAM:_FA7' => new CustomElement(I18N::translate('Fact 7')), - 'HEAD:_SCHEMA:FAM:_FA8' => new CustomElement(I18N::translate('Fact 8')), - 'HEAD:_SCHEMA:FAM:_FA9' => new CustomElement(I18N::translate('Fact 9')), - 'HEAD:_SCHEMA:FAM:_M*:LABL' => new CustomElement(I18N::translate('Label')), - 'HEAD:_SCHEMA:FAM:_MEND' => new CustomElement(I18N::translate('Marriage ending status')), - 'HEAD:_SCHEMA:FAM:_MSTAT' => new CustomElement(I18N::translate('Marriage beginning status')), - 'HEAD:_SCHEMA:INDI' => new CustomElement(I18N::translate('Individual')), - 'HEAD:_SCHEMA:INDI:_FA*:LABL' => new CustomElement(I18N::translate('Label')), - 'HEAD:_SCHEMA:INDI:_FA1' => new CustomElement(I18N::translate('Fact 1')), - 'HEAD:_SCHEMA:INDI:_FA10' => new CustomElement(I18N::translate('Fact 10')), - 'HEAD:_SCHEMA:INDI:_FA11' => new CustomElement(I18N::translate('Fact 11')), - 'HEAD:_SCHEMA:INDI:_FA12' => new CustomElement(I18N::translate('Fact 12')), - 'HEAD:_SCHEMA:INDI:_FA13' => new CustomElement(I18N::translate('Fact 13')), - 'HEAD:_SCHEMA:INDI:_FA2' => new CustomElement(I18N::translate('Fact 2')), - 'HEAD:_SCHEMA:INDI:_FA3' => new CustomElement(I18N::translate('Fact 3')), - 'HEAD:_SCHEMA:INDI:_FA4' => new CustomElement(I18N::translate('Fact 4')), - 'HEAD:_SCHEMA:INDI:_FA5' => new CustomElement(I18N::translate('Fact 5')), - 'HEAD:_SCHEMA:INDI:_FA6' => new CustomElement(I18N::translate('Fact 6')), - 'HEAD:_SCHEMA:INDI:_FA7' => new CustomElement(I18N::translate('Fact 7')), - 'HEAD:_SCHEMA:INDI:_FA8' => new CustomElement(I18N::translate('Fact 8')), - 'HEAD:_SCHEMA:INDI:_FA9' => new CustomElement(I18N::translate('Fact 9')), - 'HEAD:_SCHEMA:INDI:_FREL' => new CustomElement('Relationship to father'), - 'HEAD:_SCHEMA:INDI:_M*:LABL' => new CustomElement(I18N::translate('Label')), - 'HEAD:_SCHEMA:INDI:_MREL' => new CustomElement('Relationship to mother'), - 'INDI:*:SOUR:_APID' => new CustomElement('Ancestry.com source identifier'), - 'INDI:*:SOUR:_LINK' => new CustomElement('External link'), - 'INDI:NAME:_AKA' => new NamePersonal(I18N::translate('Also known as'), []), - 'INDI:NAME:_MARNM' => new NamePersonal(I18N::translate('Married name'), []), - 'INDI:_CIRC' => new CustomElement('Circumcision'), - 'INDI:_DCAUSE' => new CustomElement(I18N::translate('Cause of death')), - 'INDI:_DEG' => new CustomElement(I18N::translate('Degree')), - 'INDI:_DNA' => new CustomElement(I18N::translate('DNA markers')), - 'INDI:_ELEC' => new CustomElement('Elected'), - 'INDI:_EMPLOY' => new CustomElement('Employment'), - 'INDI:_EXCM' => new CustomElement('Excommunicated'), - 'INDI:_FA1' => new CustomElement('Fact 1'), - 'INDI:_FA10' => new CustomElement('Fact 10'), - 'INDI:_FA11' => new CustomElement('Fact 11'), - 'INDI:_FA12' => new CustomElement('Fact 12'), - 'INDI:_FA13' => new CustomElement('Fact 13'), - 'INDI:_FA2' => new CustomElement('Fact 2'), - 'INDI:_FA3' => new CustomElement('Fact 3'), - 'INDI:_FA4' => new CustomElement('Fact 4'), - 'INDI:_FA5' => new CustomElement('Fact 5'), - 'INDI:_FA6' => new CustomElement('Fact 6'), - 'INDI:_FA7' => new CustomElement('Fact 7'), - 'INDI:_FA8' => new CustomElement('Fact 8'), - 'INDI:_FA9' => new CustomElement('Fact 9'), - 'INDI:_MDCL' => new CustomElement('Medical'), - 'INDI:_MILT' => new CustomElement(I18N::translate('Military service')), - 'INDI:_MILTID' => new CustomElement('Military ID number'), - 'INDI:_MISN' => new CustomElement('Mission'), - 'INDI:_NAMS' => new CustomElement(I18N::translate('Namesake')), - 'INDI:_UNKN' => new CustomElement(I18N::translate('Unknown')), // Special individual ID code for later file comparisons - // The context and meaning of these tags is unknown - '_FOOT' => new CustomElement(''), - '_FUN' => new CustomElement(''), - '_JUST' => new CustomElement(''), - '_PHOTO' => new CustomElement(''), - ]); - - // Gedcom 5.3 extensions - $this->register([ - 'EVEN' => new CustomElement('Event'), - 'EVEN:*:*:NAME' => new CustomElement(I18N::translate('Name')), - 'EVEN:*:AUDIO' => new CustomElement(I18N::translate('Audio')), - 'EVEN:*:BROT' => new PlaceName('Brother'), - 'EVEN:*:BUYR' => new PlaceName('Buyer'), - 'EVEN:*:CHIL' => new PlaceName('Child'), - 'EVEN:*:DATE' => new DateValue('Date'), - 'EVEN:*:FATH' => new PlaceName('Father'), - 'EVEN:*:GODP' => new PlaceName('Godparent'), - 'EVEN:*:HDOH' => new PlaceName('Head of household'), - 'EVEN:*:HEIR' => new PlaceName('Heir'), - 'EVEN:*:HFAT' => new PlaceName('Husband’s father'), - 'EVEN:*:HMOT' => new PlaceName('Husband’s mother'), - 'EVEN:*:HUSB' => new PlaceName('Husband'), - 'EVEN:*:IMAGE' => new CustomElement('Image'), - 'EVEN:*:INDI' => new PlaceName('Individual'), - 'EVEN:*:INFT' => new PlaceName('Informant'), - 'EVEN:*:LEGA' => new PlaceName('Legatee'), - 'EVEN:*:MBR' => new PlaceName('Member'), - 'EVEN:*:MOTH' => new PlaceName('Mother'), - 'EVEN:*:OFFI' => new PlaceName('Official'), - 'EVEN:*:PARE' => new PlaceName('Parent'), - 'EVEN:*:PHOTO' => new CustomElement(I18N::translate('Photo')), - 'EVEN:*:PHUS' => new PlaceName('Previous husband'), - 'EVEN:*:PLAC' => new PlaceName('Place'), - 'EVEN:*:PWIF' => new PlaceName('Previous wife'), - 'EVEN:*:RECO' => new PlaceName('Recorder'), - 'EVEN:*:REL' => new PlaceName('Relative'), - 'EVEN:*:SELR' => new PlaceName('Seller'), - 'EVEN:*:SIBL' => new PlaceName('Sibling'), - 'EVEN:*:SIST' => new PlaceName('Sister'), - 'EVEN:*:SPOU' => new PlaceName('Spouse'), - 'EVEN:*:TXPY' => new PlaceName('Taxpayer'), - 'EVEN:*:VIDEO' => new CustomElement(I18N::translate('Video')), - 'EVEN:*:WFAT' => new PlaceName('Wife’s father'), - 'EVEN:*:WIFE' => new PlaceName('Wife'), - 'EVEN:*:WITN' => new PlaceName('Witness'), - 'EVEN:*:WMOT' => new PlaceName('Wife’s mother'), - 'EVEN:TYPE' => new CustomElement('Type of event'), - 'FAM:*:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'FAM:*:PLAC:SITE' => new CustomElement('Site'), - 'FAM:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'FAM:AUDIO' => new CustomElement(I18N::translate('Audio')), - 'FAM:IMAGE' => new CustomElement('Image'), - 'FAM:PHOTO' => new CustomElement(I18N::translate('Photo')), - 'FAM:VIDEO' => new CustomElement(I18N::translate('Video')), - 'HEAD:SCHEMA' => new CustomElement(I18N::translate('Unknown')), - 'HEAD:SCHEMA:FAM' => new CustomElement(I18N::translate('Family')), - 'HEAD:SCHEMA:FAM:*:_*' => new CustomElement('Custom event'), - 'HEAD:SCHEMA:FAM:*:_*:DEFN' => new CustomElement('Definition'), - 'HEAD:SCHEMA:FAM:*:_*:ISA' => new CustomElement('Type of event'), - 'HEAD:SCHEMA:FAM:*:_*:LABL' => new CustomElement('Label'), - 'HEAD:SCHEMA:FAM:_*' => new CustomElement('Custom event'), - 'HEAD:SCHEMA:FAM:_*:DEFN' => new CustomElement('Definition'), - 'HEAD:SCHEMA:FAM:_*:ISA' => new CustomElement('Type of event'), - 'HEAD:SCHEMA:FAM:_*:LABL' => new CustomElement('Label'), - 'HEAD:SCHEMA:INDI' => new CustomElement(I18N::translate('Individual')), - 'HEAD:SCHEMA:INDI:*:_*' => new CustomElement('Custom event'), - 'HEAD:SCHEMA:INDI:*:_*:DEFN' => new CustomElement('Definition'), - 'HEAD:SCHEMA:INDI:*:_*:ISA' => new CustomElement('Type of event'), - 'HEAD:SCHEMA:INDI:*:_*:LABL' => new CustomElement('Label'), - 'HEAD:SCHEMA:INDI:_*' => new CustomElement('Custom event'), - 'HEAD:SCHEMA:INDI:_*:DEFN' => new CustomElement('Definition'), - 'HEAD:SCHEMA:INDI:_*:ISA' => new CustomElement('Type of event'), - 'HEAD:SCHEMA:INDI:_*:LABL' => new CustomElement('Label'), - 'INDI:*:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'INDI:*:PLAC:SITE' => new CustomElement('Site'), - 'INDI:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'INDI:AUDIO' => new CustomElement(I18N::translate('Audio')), - 'INDI:BURI:PLAC:CEME' => new CustomElement(I18N::translate('Cemetery')), - 'INDI:BURI:PLAC:CEME:PLOT' => new CustomElement('Burial plot'), - 'INDI:IMAGE' => new CustomElement('Image'), - 'INDI:NAMR' => new CustomElement(I18N::translate('Religious name')), - 'INDI:NAMS' => new CustomElement(I18N::translate('Namesake')), - 'INDI:PHOTO' => new CustomElement(I18N::translate('Photo')), - 'INDI:SIGN' => new CustomElement('Signature'), - 'INDI:VIDEO' => new CustomElement(I18N::translate('Video')), - 'REPO:CALN:ITEM' => new CustomElement('Item'), - 'REPO:CALN:PAGE' => new CustomElement('Page'), - 'REPO:CALN:SHEE' => new CustomElement('Sheet'), - 'REPO:CNTC' => new CustomElement('Contact person'), - 'REPO:MEDI' => new SourceMediaType(I18N::translate('Media type')), - 'REPO:REFN' => new CustomElement('Reference number'), - 'SOUR:AUDIO' => new CustomElement(I18N::translate('Audio')), - 'SOUR:CENS' => new CustomElement('Census'), - 'SOUR:CENS:DATE' => new CustomElement('Census'), - 'SOUR:CENS:DWEL' => new CustomElement('Dwelling number'), - 'SOUR:CENS:FAMN' => new CustomElement('Family number'), - 'SOUR:CENS:LINE' => new CustomElement('Line number'), - 'SOUR:CLAS' => new CustomElement('Source classification'), - 'SOUR:CPLR' => new CustomElement('Compiler'), - 'SOUR:EDTR' => new CustomElement('Editor'), - 'SOUR:EVEN' => new CustomElement('Source events'), - 'SOUR:FIDE' => new CustomElement('Fidelity'), - 'SOUR:FILM' => new CustomElement(I18N::translate('Microfilm')), - 'SOUR:IMAGE' => new CustomElement('Image'), - 'SOUR:INDX' => new CustomElement('Indexed'), - 'SOUR:INTV' => new CustomElement('Interviewer'), - 'SOUR:ORIG' => new CustomElement('Originator'), - 'SOUR:ORIG:NAME' => new CustomElement('Name'), - 'SOUR:ORIG:NOTE' => new CustomElement('Note'), - 'SOUR:ORIG:TYPE' => new CustomElement('Type'), - 'SOUR:PERI' => new CustomElement('Date period'), - 'SOUR:PHOTO' => new CustomElement(I18N::translate('Photo')), - 'SOUR:PUBL:DATE' => new CustomElement('Date'), - 'SOUR:PUBL:EDTN' => new CustomElement('Edition'), - 'SOUR:PUBL:ISSU' => new CustomElement('Issue'), - 'SOUR:PUBL:LCCN' => new CustomElement('Library of Congress call number'), - 'SOUR:PUBL:NAME' => new CustomElement('Name'), - 'SOUR:PUBL:PUBR' => new CustomElement('Publisher'), - 'SOUR:PUBL:SERS' => new CustomElement('Series'), - 'SOUR:PUBL:TYPE' => new CustomElement('Type'), - 'SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'SOUR:RECO' => new CustomElement('Recording agency?'), - 'SOUR:REFS' => new XrefSource('Referenced source'), - 'SOUR:REPO:DPRT:ARVL' => new CustomElement('Departure'), - 'SOUR:REPO:DPRT:ARVL:DATE' => new DateValue('Date'), - 'SOUR:REPO:DPRT:ARVL:PLAC' => new PlaceName('Place'), - 'SOUR:REPO:NAME' => new CustomElement('Name of vessel'), - 'SOUR:REPO:NOTE' => new NoteStructure(I18N::translate('Note')), - 'SOUR:REPO:PORT' => new CustomElement('Port'), - 'SOUR:REPO:PORT:ARVL' => new CustomElement('Arrival'), - 'SOUR:REPO:PORT:ARVL:DATE' => new DateValue('Date'), - 'SOUR:REPO:PORT:ARVL:PLAC' => new PlaceName('Place'), - 'SOUR:REPO:TEXT' => new TextFromSource(I18N::translate('Text')), - 'SOUR:SEQU' => new CustomElement('Sequence'), - 'SOUR:STAT' => new CustomElement('Search status'), - 'SOUR:STAT:DATE' => new DateValue('Date'), - 'SOUR:TEXT' => new TextFromSource(I18N::translate('Text')), - 'SOUR:TYPE' => new CustomElement('Type of source'), - 'SOUR:VIDEO' => new CustomElement(I18N::translate('Video')), - 'SOUR:XLTR' => new CustomElement('Translator'), - ]); - - // Gedcom 5.5 extensions - $this->register([ - 'OBJE:BLOB' => new UnknownElement(I18N::translate('Binary data object')), - ]); - - // Gedcom-L extensions - $this->register([ - 'FAM:*:ADDR:_NAME' => new CustomElement('Name of addressee'), - 'FAM:*:PLAC:_GOV' => new GovIdentifier(I18N::translate('GOV identifier')), - 'FAM:*:PLAC:_LOC' => new XrefLocation(I18N::translate('Location')), - 'FAM:*:PLAC:_MAIDENHEAD' => new MaidenheadLocator('Maidenhead locator'), - 'FAM:*:PLAC:_POST' => new AddressPostalCode('Postal code'), - 'FAM:*:PLAC:_POST:DATE' => new DateValue(I18N::translate('Date')), - 'FAM:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), - 'FAM:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), - 'FAM:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), - 'FAM:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), - 'FAM:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), - 'FAM:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), - 'FAM:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), - 'FAM:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), - 'FAM:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), - 'FAM:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), - 'FAM:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), - 'FAM:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), - 'FAM:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'FAM:*:_WITN' => new CustomElement('Witness'), - 'FAM:_STAT' => new FamilyStatusText(I18N::translate('Family status'), ['DATE' => '0:1', 'PLAC' => '0:1', 'NOTE' => '0:M', 'SOUR' => '0:M']), - 'FAM:_TODO' => new ResearchTask(I18N::translate('Research task'), ['DESC' => '1:1', '_CAT' => '0:1', '_PRTY' => '0:1', 'TYPE' => '0:1', 'NOTE' => '0:M', 'DATA' => '0:1', 'STAT' => '0:1', '_CDATE' => '0:1', '_RDATE' => '0:1', 'REPO' => '0:1', '_UID' => '0:M']), - 'FAM:_TODO:DATA' => new SubmitterText(I18N::translate('The solution')), - 'FAM:_TODO:DATE' => new DateValue(I18N::translate('Creation date')), - 'FAM:_TODO:DESC' => new CustomElement(I18N::translate('Description')), - 'FAM:_TODO:NOTE' => new SubmitterText(I18N::translate('The problem')), - 'FAM:_TODO:REPO' => new XrefRepository('Repository', []), - 'FAM:_TODO:STAT' => new ResearchTaskStatus(I18N::translate('Status')), - 'FAM:_TODO:TYPE' => new ResearchTaskType(I18N::translate('Type of research task')), - 'FAM:_TODO:_CAT' => new CustomElement(I18N::translate('Category')), - 'FAM:_TODO:_CDATE' => new DateValue(I18N::translate('Completion date')), - 'FAM:_TODO:_PRTY' => new ResearchTaskPriority(I18N::translate('Priority')), - 'FAM:_TODO:_RDATE' => new DateValue(I18N::translate('Reminder date')), - 'FAM:_UID' => new PafUid(I18N::translate('Unique identifier')), - 'HEAD:SOUR:CORP:ADDR:_NAME' => new CustomElement('Name of addressee'), - 'HEAD:_SCHEMA' => new EmptyElement(I18N::translate('Schema')), - 'HEAD:_SCHEMA:*' => new EmptyElement(I18N::translate('Base GEDCOM tag')), - 'HEAD:_SCHEMA:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), - 'HEAD:_SCHEMA:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), - 'HEAD:_SCHEMA:*:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), - 'HEAD:_SCHEMA:*:*:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), - 'HEAD:_SCHEMA:*:*:*:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), - 'HEAD:_SCHEMA:*:*:*:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), - 'HEAD:_SCHEMA:*:*:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), - 'HEAD:_SCHEMA:*:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), - 'HEAD:_SCHEMA:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), - 'HEAD:_SCHEMA:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), - 'INDI:*:ADDR:_NAME' => new CustomElement('Name of addressee'), - 'INDI:*:PLAC:_GOV' => new GovIdentifier(I18N::translate('GOV identifier')), - 'INDI:*:PLAC:_LOC' => new XrefLocation(I18N::translate('Location')), - 'INDI:*:PLAC:_MAIDENHEAD' => new MaidenheadLocator('Maidenhead locator'), - 'INDI:*:PLAC:_POST' => new AddressPostalCode('Postal code'), - 'INDI:*:PLAC:_POST:DATE' => new DateValue(I18N::translate('Date')), - 'INDI:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), - 'INDI:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), - 'INDI:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), - 'INDI:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), - 'INDI:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), - 'INDI:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), - 'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), - 'INDI:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), - 'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), - 'INDI:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), - 'INDI:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), - 'INDI:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), - 'INDI:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'INDI:*:_WITN' => new CustomElement('Witness'), - 'INDI:BAPM:_GODP' => new CustomElement('Godparent'), - 'INDI:CHR:_GODP' => new CustomElement('Godparent'), - 'INDI:NAME:_RUFNAME' => new NamePieceGiven(I18N::translate('Rufname')), - 'INDI:OBJE:_PRIM' => new CustomElement(I18N::translate('Highlighted image')), - 'INDI:SEX' => new SexXValue(I18N::translate('Gender')), - 'INDI:_TODO' => new ResearchTask(I18N::translate('Research task')), - 'INDI:_TODO:DATA' => new SubmitterText(I18N::translate('The solution')), - 'INDI:_TODO:DATE' => new DateValue(I18N::translate('Creation date')), - 'INDI:_TODO:DESC' => new CustomElement(I18N::translate('Description')), - 'INDI:_TODO:NOTE' => new SubmitterText(I18N::translate('The problem')), - 'INDI:_TODO:REPO' => new XrefRepository('Repository', []), - 'INDI:_TODO:STAT' => new ResearchTaskStatus(I18N::translate('Status')), - 'INDI:_TODO:TYPE' => new ResearchTaskType(I18N::translate('Type of research task')), - 'INDI:_TODO:_CAT' => new CustomElement(I18N::translate('Category')), - 'INDI:_TODO:_CDATE' => new DateValue(I18N::translate('Completion date')), - 'INDI:_TODO:_PRTY' => new ResearchTaskPriority(I18N::translate('Priority')), - 'INDI:_TODO:_RDATE' => new DateValue(I18N::translate('Reminder date')), - 'INDI:_UID' => new PafUid(I18N::translate('Unique identifier')), - 'NOTE:_UID' => new PafUid(I18N::translate('Unique identifier')), - 'OBJE:FILE:_PRIM' => new CustomElement(I18N::translate('Highlighted image')), - 'OBJE:_UID' => new PafUid(I18N::translate('Unique identifier')), - 'REPO:ADDR:_NAME' => new CustomElement('Name of addressee'), - 'REPO:_UID' => new PafUid(I18N::translate('Unique identifier')), - 'SOUR:_UID' => new PafUid(I18N::translate('Unique identifier')), - 'SUBM:ADDR:_NAME' => new CustomElement('Name of addressee'), - 'SUBM:_UID' => new PafUid(I18N::translate('Unique identifier')), - 'SUBN:_UID' => new PafUid(I18N::translate('Unique identifier')), - '_LOC' => new LocationRecord(I18N::translate('Location')), - '_LOC:CHAN' => new Change(I18N::translate('Last change')), - '_LOC:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), - '_LOC:CHAN:DATE:TIME' => new TimeValue(I18N::translate('Time')), - '_LOC:CHAN:NOTE' => new NoteStructure(I18N::translate('Note')), - '_LOC:EVEN' => new EventDescriptor(I18N::translate('Event'), ['TYPE' => '0:1']), - '_LOC:EVEN:TYPE' => new EventAttributeType(I18N::translate('Type of event')), - '_LOC:MAP' => new EmptyElement(I18N::translate('Coordinates')), - '_LOC:MAP:LATI' => new PlaceLatitude(I18N::translate('Latitude')), - '_LOC:MAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude')), - '_LOC:NAME' => new PlaceName(I18N::translate('Place'), ['ABBR' => '0:1', 'DATE' => '0:1', 'LANG' => '0:1', 'SOUR' => '0:M']), - '_LOC:NAME:ABBR' => new CustomElement(I18N::translate('Abbreviation')), - '_LOC:NAME:ABBR:TYPE' => new CustomElement(I18N::translate('Type of abbreviation')), - '_LOC:NAME:DATE' => new DateValue(I18N::translate('Date')), - '_LOC:NAME:LANG' => new LanguageId(I18N::translate('Language')), - '_LOC:NAME:SOUR' => new XrefSource(I18N::translate('Source')), - '_LOC:NOTE' => new NoteStructure(I18N::translate('Note')), - '_LOC:OBJE' => new XrefMedia(I18N::translate('Media')), - '_LOC:RELI' => new ReligiousAffiliation('Religion', []), - '_LOC:SOUR' => new XrefSource(I18N::translate('Source')), - '_LOC:SOUR:DATA' => new SourceData(I18N::translate('Data')), - '_LOC:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), - '_LOC:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), - '_LOC:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), - '_LOC:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), - '_LOC:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), - '_LOC:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), - '_LOC:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), - '_LOC:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - '_LOC:TYPE' => new CustomElement(I18N::translate('Type of location')), - '_LOC:TYPE:DATE' => new DateValue(I18N::translate('Date')), - '_LOC:TYPE:SOUR' => new XrefSource(I18N::translate('Source')), - '_LOC:TYPE:_GOVTYPE' => new CustomElement('GOV identifier type'), - '_LOC:_AIDN' => new CustomElement('Administrative ID'), - '_LOC:_AIDN:DATE' => new DateValue(I18N::translate('Date')), - '_LOC:_AIDN:SOUR' => new XrefSource(I18N::translate('Source')), - '_LOC:_AIDN:TYPE' => new CustomElement(I18N::translate('Type of administrative ID')), - '_LOC:_DMGD' => new CustomElement('Demographic data'), - '_LOC:_DMGD:DATE' => new DateValue(I18N::translate('Date')), - '_LOC:_DMGD:SOUR' => new XrefSource(I18N::translate('Source')), - '_LOC:_DMGD:TYPE' => new CustomElement(I18N::translate('Type of demographic data')), - '_LOC:_GOV' => new GovIdentifier(I18N::translate('GOV identifier')), - '_LOC:_LOC' => new XrefLocation(I18N::translate('Parent'), ['DATE' => '0:1', 'SOUR' => '0:M', 'TYPE' => '0:1']), - '_LOC:_LOC:DATE' => new DateValue(I18N::translate('Date')), - '_LOC:_LOC:SOUR' => new XrefSource(I18N::translate('Source')), - '_LOC:_LOC:TYPE' => new HierarchicalRelationship(I18N::translate('Hierarchical relationship')), - '_LOC:_MAIDENHEAD' => new MaidenheadLocator('Maidenhead locator'), - '_LOC:_POST' => new AddressPostalCode(I18N::translate('Postal code')), - '_LOC:_POST:DATE' => new DateValue(I18N::translate('Date')), - '_LOC:_POST:SOUR' => new XrefSource(I18N::translate('Source')), - '_LOC:_UID' => new PafUid(I18N::translate('Unique identifier')), - '_LOC:*:SOUR:DATA' => new SourceData(I18N::translate('Data')), - '_LOC:*:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), - '_LOC:*:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), - '_LOC:*:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), - '_LOC:*:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), - '_LOC:*:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), - '_LOC:*:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), - '_LOC:*:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), - '_LOC:*:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - ]); - - // Legacy extensions - $this->register([ - 'FAM:*:ADDR:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), - 'FAM:*:PLAC:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), - 'FAM:*:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), - 'FAM:*:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), - 'FAM:CHIL:_FREL' => new CustomElement('The Relationship of a child to the Father (under a CHIL block under a FAM record).'), - 'FAM:CHIL:_MREL' => new CustomElement('The Relationship of a child to the Mother (under a CHIL block under a FAM record).'), - 'FAM:CHIL:_STAT' => new CustomElement('The Status of a marriage (Married, Unmarried, etc.). Also the Status of a child (Twin, Triplet, etc.). (The marriage status of Divorced is exported using a DIV tag.)'), - 'FAM:EVEN:_OVER' => new CustomElement('An event sentence override (under an EVEN block).'), - 'FAM:MARR:_STAT' => new CustomElement('The Status of a marriage (Married, Unmarried, etc.). Also the Status of a child (Twin, Triplet, etc.). (The marriage status of Divorced is exported using a DIV tag.)'), - 'FAM:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), - 'FAM:_NONE' => new CustomElement('Indicates that a couple had no children (under a FAM record).'), - 'HEAD:_EVENT_DEFN' => new CustomElement('Indicates the start of an Event Definition record that describes the attributes of an event or fact.'), - 'HEAD:_EVENT_DEFN:_CONF_FLAG' => new CustomElement('Indicates that an event is Confidential or Private (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_DATE_TYPE' => new CustomElement('Indicates whether or not a Date field is shown for a specific event (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_DESC_FLAG' => new CustomElement('Indicates whether or not a Description field is shown for a specific event (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_PLACE_TYPE' => new CustomElement('Indicates whether or not a Place field is shown for a specific event (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_PP_EXCLUDE' => new CustomElement('Indicates that an event is to be Excluded from the Potential Problems reporting (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN1' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN2' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN3' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN4' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN5' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN6' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN7' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SEN8' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENDOF' => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENDOM' => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENDOU' => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENDPF' => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENDPM' => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENDPU' => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENF' => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENM' => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENPOF' => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENPOM' => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENPOU' => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_EVENT_DEFN:_SENU' => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'), - 'HEAD:_PLAC_DEFN' => new CustomElement('Indicates the start of a Place Definition record that describes the attribute of a place.'), - 'HEAD:_PLAC_DEFN:_PREP' => new CustomElement('A location Preposition (under a _PLAC_DEFN record).'), - 'INDI:*:ADDR:_LIST3 YES' => new CustomElement('Indicates that a person’s address is part of the Birthday grouping (under an ADDR block).'), - 'INDI:*:ADDR:_LIST4 YES' => new CustomElement('Indicates that a person’s address is part of the Research grouping (under an ADDR block).'), - 'INDI:*:ADDR:_LIST5 YES' => new CustomElement('Indicates that a person’s address is part of the Christmas grouping (under an ADDR block).'), - 'INDI:*:ADDR:_LIST6 YES' => new CustomElement('Indicates that a person’s address is part of the Holiday grouping (under an ADDR block).'), - 'INDI:*:ADDR:_NAME' => new CustomElement('The name of an individual as part of an address (under an ADDR block).'), - 'INDI:*:ADDR:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), - 'INDI:*:ADDR:_SORT' => new CustomElement('The spelling of a name to be used when sorting addresses for a report (under an ADDR block).'), - 'INDI:*:ADDR:_TAG' => new CustomElement('Indicates that an address, or place has been tagged. Also used for Tag 1 selection for an individual.'), - 'INDI:*:PLAC:_TAG' => new CustomElement('Indicates that an address, or place has been tagged. Also used for Tag 1 selection for an individual.'), - 'INDI:*:PLAC:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), - 'INDI:*:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), - 'INDI:*:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), - 'INDI:ADDR:_EMAIL' => new CustomElement('An email address (under an ADDR block).'), - 'INDI:ADDR:_LIST1 YES' => new CustomElement('Indicates that a person’s address is part of the Newsletter grouping (under an ADDR block).'), - 'INDI:ADDR:_LIST2 YES' => new CustomElement('Indicates that a person’s address is part of the Family Association grouping (under an ADDR block).'), - 'INDI:EVEN:_OVER' => new CustomElement('An event sentence override (under an EVEN block).'), - 'INDI:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), - 'INDI:_TAG' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG2' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG3' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG4' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG5' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG6' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG7' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG8' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TAG9' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), - 'INDI:_TODO' => new CustomElement('Research task'), - 'INDI:_TODO:_CAT' => new CustomElement('The Category of a To-Do item (under a _TODO record).'), - 'INDI:_TODO:_CDATE' => new CustomElement('Closed Date of a To-Do item (under a _TODO record).'), - 'INDI:_TODO:_LOCL' => new CustomElement('The Locality of a To-Do item (under a _TODO record).'), - 'INDI:_TODO:_RDATE' => new CustomElement('Reminder date on to-do items. (Under a _TODO record.)'), - 'INDI:_UID' => new CustomElement('A Unique Identification Number given to each individual in a family file.'), - 'INDI:_URL' => new CustomElement('An Internet address (under an INDI record).'), - 'OBJE:_DATE' => new CustomElement('A date associated with a multimedia object, usually a picture or video (under an OBJE block).'), - 'OBJE:_PRIM' => new CustomElement('Means a multimedia object, usually a picture, is the Primary object (the one that is shown on a report) (under an OBJE block).'), - 'OBJE:_SCBK' => new CustomElement('Indicates that a Picture is tagged to be included in a scrapbook report (under an OBJE block).'), - 'OBJE:_SOUND' => new CustomElement('A sound file name that is attached to a picture (under an OBJE block).'), - 'OBJE:_TYPE' => new CustomElement('The type of a multimedia object: Photo, Sound, or Video (under an OBJE block).'), - 'SOUR:_ITALIC Y' => new CustomElement('Indicates that a source title should be printed on a report in italics (under a SOUR record).'), - 'SOUR:_PAREN' => new CustomElement('Indicates that the Publication Facts of a source should be printed within parentheses on a report (under a SOUR record).'), - 'SOUR:_QUOTED Y' => new CustomElement('Indicates that a source title should be printed within quotes on a report (under a SOUR record).'), - 'SOUR:_TAG NO' => new CustomElement('When used under a SOUR record, indicates to exclude the source citation detail on reports.'), - 'SOUR:_TAG2 NO' => new CustomElement('When used under a SOUR record, indicates to exclude the source citation on reports.'), - 'SOUR:_TAG3 YES' => new CustomElement('When used under a SOUR record, indicates to include the source citation detail text on reports.'), - 'SOUR:_TAG4 YES' => new CustomElement('When used under a SOUR record, indicates to include the source citation detail notes on reports.'), - '_PREF' => new CustomElement('Indicates a Preferred spouse, child or parents.'), // How is this used? - ]); - - // Personal Ancestral File extensions - $this->register([ - 'INDI:NAME:_ADPN' => new NamePersonal(I18N::translate('Adopted name'), []), - 'INDI:NAME:_AKA' => new NamePersonal(I18N::translate('Also known as'), []), - 'INDI:NAME:_AKAN' => new NamePersonal(I18N::translate('Also known as'), []), - 'INDI:_EMAIL' => new AddressEmail(I18N::translate('Email address')), - 'URL' => new CustomElement(I18N::translate('URL')), - '_HEB' => new CustomElement(I18N::translate('Hebrew')), - '_NAME' => new CustomElement(I18N::translate('Mailing name')), - '_SCBK' => new CustomElement(I18N::translate('Scrapbook')), - '_SSHOW' => new CustomElement(I18N::translate('Slide show')), - '_TYPE' => new CustomElement(I18N::translate('Media type')), - '_URL' => new CustomElement(I18N::translate('URL')), - ]); - - // PhpGedView extensions - $this->register([ - 'FAM:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), - 'FAM:COMM' => new CustomElement(I18N::translate('Comment')), - 'INDI:*:ASSO' => new XrefAssociate(I18N::translate('Associate')), - 'INDI:*:ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), - 'INDI:*:PLAC:_HEB' => new NoteStructure(I18N::translate('Place in Hebrew')), - 'INDI:ADDR' => new AddressLine(I18N::translate('Address'), []), - 'INDI:BIRT:DATE:TIME' => new TimeValue(I18N::translate('Time')), - 'INDI:BURI:CEME' => new CustomElement(I18N::translate('Cemetery')), - 'INDI:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), - 'INDI:COMM' => new CustomElement(I18N::translate('Comment')), - 'INDI:DEAT:DATE:TIME' => new TimeValue(I18N::translate('Time')), - 'INDI:EMAIL' => new AddressEmail(I18N::translate('Email address')), - 'INDI:NAME:_HEB' => new NamePersonal(I18N::translate('Name in Hebrew'), []), - 'INDI:_FNRL' => new CustomEvent(I18N::translate('Funeral')), - 'INDI:_HOL' => new CustomEvent(I18N::translate('Holocaust')), - 'INDI:_MILI' => new CustomEvent(I18N::translate('Military')), - 'INDI:_PGV_OBJS' => new XrefMedia(I18N::translate('Re-order media')), - 'NOTE:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), - 'OBJE:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), - 'OBJE:_PRIM' => new CustomElement(I18N::translate('Highlighted image')), - 'OBJE:_THUM' => new CustomElement(I18N::translate('Thumbnail image')), - 'REPO:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), - 'SOUR:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), - 'SOUR:SERV' => new CustomElement(I18N::translate('Remote server')), - 'SOUR:URL' => new AddressWebPage(I18N::translate('URL')), - 'SOUR:URL:TYPE' => new CustomElement(I18N::translate('Type')), // e.g. "FamilySearch" - 'SOUR:URL:_BLOCK' => new CustomElement(I18N::translate('Block')), // "e.g. "false" - 'SOUR:_DBID' => new CustomElement(I18N::translate('Database name')), - 'SOUR:_DBID:_PASS' => new CustomElement(I18N::translate('Database password')), - 'SOUR:_DBID:_PASS:RESN' => new RestrictionNotice(I18N::translate('Restriction')), - 'SOUR:_DBID:_USER' => new CustomElement(I18N::translate('Database user account')), - ]); - - // Reunion extensions - $this->register([ - 'INDI:EMAL' => new AddressEmail(I18N::translate('Email address')), - 'INDI:CITN' => new CustomElement(I18N::translate('Citizenship')), - 'INDI:_LEGA' => new CustomElement(I18N::translate('Legatee')), - 'INDI:_MDCL' => new CustomElement(I18N::translate('Medical')), - 'INDI:_PURC' => new CustomElement('Land purchase'), - 'INDI:_SALE' => new CustomElement('Land sale'), - ]); - - // Roots Magic extensions - $this->register([ - 'INDI:_DNA' => new CustomElement(I18N::translate('DNA markers')), - 'INDI:_WEBTAG' => new CustomElement(I18N::translate('External link')), - 'INDI:_WEBTAG:NAME' => new CustomElement(I18N::translate('Text')), - 'INDI:_WEBTAG:URL' => new AddressWebPage(I18N::translate('URL')), - 'SOUR:_BIBL' => new CustomElement(I18N::translate('Bibliography')), - 'SOUR:_SUBQ' => new CustomElement(I18N::translate('Abbreviation')), - ]); - - // webtrees extensions - $this->register([ - 'FAM:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - 'FAM:_ASSO' => new XrefAssociate(I18N::translate('Associate')), - 'FAM:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), - 'FAM:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), - 'FAM:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), - 'FAM:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), - 'FAM:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), - 'FAM:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), - 'FAM:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), - 'FAM:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), - 'FAM:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), - 'FAM:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), - 'FAM:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), - 'FAM:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), - 'FAM:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), - 'FAM:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'INDI:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - 'INDI:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), - 'INDI:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), - 'INDI:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), - 'INDI:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), - 'INDI:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), - 'INDI:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), - 'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), - 'INDI:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), - 'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), - 'INDI:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), - 'INDI:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), - 'INDI:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), - 'INDI:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), - 'NOTE:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - 'NOTE:RESN' => new RestrictionNotice(I18N::translate('Restriction')), - 'OBJE:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - 'OBJE:RESN' => new RestrictionNotice(I18N::translate('Restriction')), - 'REPO:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - 'REPO:RESN' => new RestrictionNotice(I18N::translate('Restriction')), - 'SOUR:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - 'SOUR:RESN' => new RestrictionNotice(I18N::translate('Restriction')), - 'SUBM:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - 'SUBM:RESN' => new RestrictionNotice(I18N::translate('Restriction')), - '_LOC:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), - '_LOC:RESN' => new RestrictionNotice(I18N::translate('Restriction')), - ]); } return $this->elements; diff --git a/app/Http/RequestHandlers/ControlPanel.php b/app/Http/RequestHandlers/ControlPanel.php index 6cde5e350a..4373ecc4ad 100644 --- a/app/Http/RequestHandlers/ControlPanel.php +++ b/app/Http/RequestHandlers/ControlPanel.php @@ -28,6 +28,7 @@ use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface; use Fisharebest\Webtrees\Module\ModuleBlockInterface; use Fisharebest\Webtrees\Module\ModuleChartInterface; use Fisharebest\Webtrees\Module\ModuleCustomInterface; +use Fisharebest\Webtrees\Module\ModuleCustomTagsInterface; use Fisharebest\Webtrees\Module\ModuleDataFixInterface; use Fisharebest\Webtrees\Module\ModuleFooterInterface; use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface; @@ -178,6 +179,8 @@ class ControlPanel implements RequestHandlerInterface 'chart_modules_disabled' => $this->module_service->findByInterface(ModuleChartInterface::class, true), 'chart_modules_enabled' => $this->module_service->findByInterface(ModuleChartInterface::class), 'custom_updates' => $custom_updates, + 'custom_tags_modules_disabled' => $this->module_service->findByInterface(ModuleCustomTagsInterface::class, true), + 'custom_tags_modules_enabled' => $this->module_service->findByInterface(ModuleCustomTagsInterface::class), 'data_fix_modules_disabled' => $this->module_service->findByInterface(ModuleDataFixInterface::class, true), 'data_fix_modules_enabled' => $this->module_service->findByInterface(ModuleDataFixInterface::class), 'other_modules' => $this->module_service->otherModules(true), diff --git a/app/Http/RequestHandlers/ModulesCustomTagsAction.php b/app/Http/RequestHandlers/ModulesCustomTagsAction.php new file mode 100644 index 0000000000..41a03a3af6 --- /dev/null +++ b/app/Http/RequestHandlers/ModulesCustomTagsAction.php @@ -0,0 +1,50 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Http\RequestHandlers; + +use Fisharebest\Webtrees\FlashMessages; +use Fisharebest\Webtrees\I18N; +use Fisharebest\Webtrees\Module\ModuleCustomTagsInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; + +use function redirect; +use function route; + +/** + * Update a list of modules. + */ +class ModulesCustomTagsAction extends AbstractModuleComponentAction +{ + /** + * @param ServerRequestInterface $request + * + * @return ResponseInterface + */ + public function handle(ServerRequestInterface $request): ResponseInterface + { + $this->updateStatus(ModuleCustomTagsInterface::class, $request); + $this->updateAccessLevel(ModuleCustomTagsInterface::class, $request); + + FlashMessages::addMessage(I18N::translate('The website preferences have been updated.'), 'success'); + + return redirect(route(ModulesCustomTagsPage::class)); + } +} diff --git a/app/Http/RequestHandlers/ModulesCustomTagsPage.php b/app/Http/RequestHandlers/ModulesCustomTagsPage.php new file mode 100644 index 0000000000..051c3a506e --- /dev/null +++ b/app/Http/RequestHandlers/ModulesCustomTagsPage.php @@ -0,0 +1,47 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Http\RequestHandlers; + +use Fisharebest\Webtrees\I18N; +use Fisharebest\Webtrees\Module\ModuleCustomTagsInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; + +use function view; + +/** + * Show a list of modules. + */ +class ModulesCustomTagsPage extends AbstractModuleComponentPage +{ + /** + * @param ServerRequestInterface $request + * + * @return ResponseInterface + */ + public function handle(ServerRequestInterface $request): ResponseInterface + { + return $this->listComponents( + ModuleCustomTagsInterface::class, + view('icons/chart') . I18N::translate('Custom tags'), + '' + ); + } +} diff --git a/app/Http/Routes/WebRoutes.php b/app/Http/Routes/WebRoutes.php index c150c19bce..a13dfe5a27 100644 --- a/app/Http/Routes/WebRoutes.php +++ b/app/Http/Routes/WebRoutes.php @@ -177,6 +177,8 @@ use Fisharebest\Webtrees\Http\RequestHandlers\ModulesBlocksAction; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesBlocksPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesChartsAction; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesChartsPage; +use Fisharebest\Webtrees\Http\RequestHandlers\ModulesCustomTagsAction; +use Fisharebest\Webtrees\Http\RequestHandlers\ModulesCustomTagsPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesDataFixesAction; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesDataFixesPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesFootersAction; @@ -386,6 +388,8 @@ class WebRoutes $router->post(ModulesBlocksAction::class, '/blocks'); $router->get(ModulesChartsPage::class, '/charts'); $router->post(ModulesChartsAction::class, '/charts'); + $router->get(ModulesCustomTagsPage::class, '/custom-tags'); + $router->post(ModulesCustomTagsAction::class, '/custom-tags'); $router->get(ModulesDataFixesPage::class, '/data-fixes'); $router->post(ModulesDataFixesAction::class, '/data-fixes'); $router->get(ModulesFootersPage::class, '/footers'); diff --git a/app/Module/CustomTagsAldfaer.php b/app/Module/CustomTagsAldfaer.php new file mode 100644 index 0000000000..37eafcbcbb --- /dev/null +++ b/app/Module/CustomTagsAldfaer.php @@ -0,0 +1,56 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CustomEvent; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsAldfaer + */ +class CustomTagsAldfaer extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'FAM:MARR_CIVIL' => new CustomEvent(I18N::translate('Civil marriage')), + 'FAM:MARR_RELIGIOUS' => new CustomEvent(I18N::translate('Religious marriage')), + 'FAM:MARR_PARTNERS' => new CustomEvent(I18N::translate('Registered partnership')), + 'FAM:MARR_UNKNOWN' => new CustomEvent(I18N::translate('Marriage type unknown')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Aldfaer™'; + } +} diff --git a/app/Module/CustomTagsAncestry.php b/app/Module/CustomTagsAncestry.php new file mode 100644 index 0000000000..9d0430cc42 --- /dev/null +++ b/app/Module/CustomTagsAncestry.php @@ -0,0 +1,55 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\CustomEvent; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsAncestry + */ +class CustomTagsAncestry extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'INDI:*:SOUR:_APID' => new CustomElement(I18N::translate('Ancestry PID')), + 'INDI:_EMPLOY' => new CustomEvent(I18N::translate('Occupation')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Ancestry™'; + } +} diff --git a/app/Module/CustomTagsBrothersKeeper.php b/app/Module/CustomTagsBrothersKeeper.php new file mode 100644 index 0000000000..2aecdb943b --- /dev/null +++ b/app/Module/CustomTagsBrothersKeeper.php @@ -0,0 +1,117 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\AddressEmail; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\CustomEvent; +use Fisharebest\Webtrees\Elements\CustomFact; +use Fisharebest\Webtrees\Elements\DateValue; +use Fisharebest\Webtrees\Elements\NamePersonal; +use Fisharebest\Webtrees\Elements\PlaceName; +use Fisharebest\Webtrees\I18N; + +/** + * Custom tags created by Brother’s Keeper + * + * Class CustomTagsBrothersKeeper + */ +class CustomTagsBrothersKeeper extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + * + * @see http://wiki-de.genealogy.net/GEDCOM/_Nutzerdef-Tag + */ + public function customTags(): array + { + return [ + 'FAM:*:_EVN' => new CustomElement('Event number'), + 'FAM:CHIL:_FREL' => new CustomElement('Relationship to father'), + 'FAM:CHIL:_MREL' => new CustomElement('Relationship to mother'), + 'FAM:_COML' => new CustomEvent(I18N::translate('Common law marriage')), + 'FAM:_MARI' => new CustomEvent(I18N::translate('Marriage intention')), + 'FAM:_MBON' => new CustomEvent(I18N::translate('Marriage bond')), + 'FAM:_NMR' => new CustomEvent(I18N::translate('Not married'), ['NOTE' => '0:M', 'SOUR' => '0:M']), + 'FAM:_PRMN' => new CustomElement(I18N::translate('Permanent number')), + 'FAM:_SEPR' => new CustomEvent(I18N::translate('Separated')), + 'FAM:_TODO' => new CustomElement(I18N::translate('Research task')), + 'INDI:*:_EVN' => new CustomElement('Event number'), + 'INDI:NAME:_ADPN' => new NamePersonal(I18N::translate('Adopted name'), []), + 'INDI:NAME:_AKAN' => new NamePersonal(I18N::translate('Also known as'), []), + 'INDI:NAME:_BIRN' => new NamePersonal(I18N::translate('Birth name'), []), + 'INDI:NAME:_CALL' => new NamePersonal('Called name', []), + 'INDI:NAME:_CENN' => new NamePersonal('Census name', []), + 'INDI:NAME:_CURN' => new NamePersonal('Current name', []), + 'INDI:NAME:_FARN' => new NamePersonal(I18N::translate('Estate name'), []), + 'INDI:NAME:_FKAN' => new NamePersonal('Formal name', []), + 'INDI:NAME:_FRKA' => new NamePersonal('Formerly known as', []), + 'INDI:NAME:_GERN' => new NamePersonal('German name', []), + 'INDI:NAME:_HEBN' => new NamePersonal(I18N::translate('Hebrew name'), []), + 'INDI:NAME:_HNM' => new NamePersonal(I18N::translate('Hebrew name'), []), + 'INDI:NAME:_INDG' => new NamePersonal('Indigenous name', []), + 'INDI:NAME:_INDN' => new NamePersonal('Indian name', []), + 'INDI:NAME:_LNCH' => new NamePersonal('Legal name change', []), + 'INDI:NAME:_MARN' => new NamePersonal('Married name', []), + 'INDI:NAME:_MARNM' => new NamePersonal('Married name', []), + 'INDI:NAME:_OTHN' => new NamePersonal('Other name', []), + 'INDI:NAME:_RELN' => new NamePersonal('Religious name', []), + 'INDI:NAME:_SHON' => new NamePersonal('Short name', []), + 'INDI:NAME:_SLDN' => new NamePersonal('Soldier name', []), + 'INDI:_ADPF' => new CustomElement(I18N::translate('Adopted by father')), + 'INDI:_ADPM' => new CustomElement(I18N::translate('Adopted by mother')), + 'INDI:_BRTM' => new CustomEvent(I18N::translate('Brit milah')), + 'INDI:_BRTM:DATE' => new DateValue(I18N::translate('Date of brit milah')), + 'INDI:_BRTM:PLAC' => new PlaceName(I18N::translate('Place of brit milah')), + 'INDI:_EMAIL' => new AddressEmail(I18N::translate('Email address')), + 'INDI:_EYEC' => new CustomFact(I18N::translate('Eye color')), + 'INDI:_FRNL' => new CustomElement(I18N::translate('Funeral')), + 'INDI:_HAIR' => new CustomFact(I18N::translate('Hair color')), + 'INDI:_HEIG' => new CustomFact(I18N::translate('Height')), + 'INDI:_INTE' => new CustomElement(I18N::translate('Interment')), + 'INDI:_MEDC' => new CustomFact(I18N::translate('Medical')), + 'INDI:_MILT' => new CustomElement(I18N::translate('Military service')), + 'INDI:_NLIV' => new CustomFact(I18N::translate('Not living')), + 'INDI:_NMAR' => new CustomEvent(I18N::translate('Never married'), ['NOTE' => '0:M', 'SOUR' => '0:M']), + 'INDI:_PRMN' => new CustomElement(I18N::translate('Permanent number')), + 'INDI:_TODO' => new CustomElement(I18N::translate('Research task')), + 'INDI:_WEIG' => new CustomFact(I18N::translate('Weight')), + 'INDI:_YART' => new CustomEvent(I18N::translate('Yahrzeit')), + // 1 XXXX + // 2 _EVN ## + // 1 ASSO @Xnnn@ + // 2 RELA Witness at event _EVN ## + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Brother’s Keeper™'; + } +} diff --git a/app/Module/CustomTagsFamilySearch.php b/app/Module/CustomTagsFamilySearch.php new file mode 100644 index 0000000000..92a956054b --- /dev/null +++ b/app/Module/CustomTagsFamilySearch.php @@ -0,0 +1,53 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\FamilySearchFamilyTreeId; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsFamilySearch + */ +class CustomTagsFamilySearch extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'INDI:_FSFTID' => /* I18N: familysearch.org */ new FamilySearchFamilyTreeId(I18N::translate('FamilySearch ID')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'FamilySearch'; + } +} diff --git a/app/Module/CustomTagsFamilyTreeBuilder.php b/app/Module/CustomTagsFamilyTreeBuilder.php new file mode 100644 index 0000000000..9264ad9a0f --- /dev/null +++ b/app/Module/CustomTagsFamilyTreeBuilder.php @@ -0,0 +1,64 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\DateValue; +use Fisharebest\Webtrees\Elements\NamePersonal; +use Fisharebest\Webtrees\Elements\PlaceName; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsFTB + */ +class CustomTagsFamilyTreeBuilder extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + '*:_UPD' => new CustomElement(I18N::translate('Last change')), // e.g. "1 _UPD 14 APR 2012 00:14:10 GMT-5" + 'INDI:NAME:_AKA' => new NamePersonal(I18N::translate('Also known as'), []), + 'OBJE:_ALBUM' => new CustomElement(I18N::translate('Album')), // XREF to an album + 'OBJE:_DATE' => new DateValue(I18N::translate('Date')), + 'OBJE:_FILESIZE' => new CustomElement(I18N::translate('File size')), + 'OBJE:_PHOTO_RIN' => new CustomElement(I18N::translate('Photo')), + 'OBJE:_PLACE' => new PlaceName(I18N::translate('Place')), + '_ALBUM:_PHOTO' => new CustomElement(I18N::translate('Photo')), + '_ALBUM:_PHOTO:_PRIN' => new CustomElement(I18N::translate('Highlighted image')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Family Tree Builder™'; + } +} diff --git a/app/Module/CustomTagsFamilyTreeMaker.php b/app/Module/CustomTagsFamilyTreeMaker.php new file mode 100644 index 0000000000..eb19e22fd1 --- /dev/null +++ b/app/Module/CustomTagsFamilyTreeMaker.php @@ -0,0 +1,148 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\NamePersonal; +use Fisharebest\Webtrees\I18N; + +/** + * Custom tags created by FamilyTreeMaker (DOS, Windows, ancestry.com) + * + * Class CustomTagsFamilyTreeMaker + */ +class CustomTagsFamilyTreeMaker extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + * + * @see http://wiki-de.genealogy.net/GEDCOM/_Nutzerdef-Tag + */ + public function customTags(): array + { + return [ + 'FAM:CHIL:_FREL' => new CustomElement(I18N::translate('Relationship to father')), + 'FAM:CHIL:_MREL' => new CustomElement(I18N::translate('Relationship to mother')), + 'FAM:_DETS' => new CustomElement(I18N::translate('Death of one spouse')), + 'FAM:_FA1' => new CustomElement(I18N::translate('Fact 1')), + 'FAM:_FA10' => new CustomElement(I18N::translate('Fact 10')), + 'FAM:_FA11' => new CustomElement(I18N::translate('Fact 11')), + 'FAM:_FA12' => new CustomElement(I18N::translate('Fact 12')), + 'FAM:_FA13' => new CustomElement(I18N::translate('Fact 13')), + 'FAM:_FA2' => new CustomElement(I18N::translate('Fact 2')), + 'FAM:_FA3' => new CustomElement(I18N::translate('Fact 3')), + 'FAM:_FA4' => new CustomElement(I18N::translate('Fact 4')), + 'FAM:_FA5' => new CustomElement(I18N::translate('Fact 5')), + 'FAM:_FA6' => new CustomElement(I18N::translate('Fact 6')), + 'FAM:_FA7' => new CustomElement(I18N::translate('Fact 7')), + 'FAM:_FA8' => new CustomElement(I18N::translate('Fact 8')), + 'FAM:_FA9' => new CustomElement(I18N::translate('Fact 9')), + 'FAM:_MEND' => new CustomElement(I18N::translate('Marriage ending status')), + 'FAM:_MSTAT' => new CustomElement(I18N::translate('Marriage beginning status')), + 'FAM:_SEPR' => new CustomElement(I18N::translate('Separation')), + 'HEAD:_SCHEMA' => new CustomElement('Schema'), + 'HEAD:_SCHEMA:FAM' => new CustomElement(I18N::translate('Family')), + 'HEAD:_SCHEMA:FAM:_FA*:LABL' => new CustomElement(I18N::translate('Label')), + 'HEAD:_SCHEMA:FAM:_FA1' => new CustomElement(I18N::translate('Fact 1')), + 'HEAD:_SCHEMA:FAM:_FA10' => new CustomElement(I18N::translate('Fact 10')), + 'HEAD:_SCHEMA:FAM:_FA11' => new CustomElement(I18N::translate('Fact 11')), + 'HEAD:_SCHEMA:FAM:_FA12' => new CustomElement(I18N::translate('Fact 12')), + 'HEAD:_SCHEMA:FAM:_FA13' => new CustomElement(I18N::translate('Fact 13')), + 'HEAD:_SCHEMA:FAM:_FA2' => new CustomElement(I18N::translate('Fact 2')), + 'HEAD:_SCHEMA:FAM:_FA3' => new CustomElement(I18N::translate('Fact 3')), + 'HEAD:_SCHEMA:FAM:_FA4' => new CustomElement(I18N::translate('Fact 4')), + 'HEAD:_SCHEMA:FAM:_FA5' => new CustomElement(I18N::translate('Fact 5')), + 'HEAD:_SCHEMA:FAM:_FA6' => new CustomElement(I18N::translate('Fact 6')), + 'HEAD:_SCHEMA:FAM:_FA7' => new CustomElement(I18N::translate('Fact 7')), + 'HEAD:_SCHEMA:FAM:_FA8' => new CustomElement(I18N::translate('Fact 8')), + 'HEAD:_SCHEMA:FAM:_FA9' => new CustomElement(I18N::translate('Fact 9')), + 'HEAD:_SCHEMA:FAM:_M*:LABL' => new CustomElement(I18N::translate('Label')), + 'HEAD:_SCHEMA:FAM:_MEND' => new CustomElement(I18N::translate('Marriage ending status')), + 'HEAD:_SCHEMA:FAM:_MSTAT' => new CustomElement(I18N::translate('Marriage beginning status')), + 'HEAD:_SCHEMA:INDI' => new CustomElement(I18N::translate('Individual')), + 'HEAD:_SCHEMA:INDI:_FA*:LABL' => new CustomElement(I18N::translate('Label')), + 'HEAD:_SCHEMA:INDI:_FA1' => new CustomElement(I18N::translate('Fact 1')), + 'HEAD:_SCHEMA:INDI:_FA10' => new CustomElement(I18N::translate('Fact 10')), + 'HEAD:_SCHEMA:INDI:_FA11' => new CustomElement(I18N::translate('Fact 11')), + 'HEAD:_SCHEMA:INDI:_FA12' => new CustomElement(I18N::translate('Fact 12')), + 'HEAD:_SCHEMA:INDI:_FA13' => new CustomElement(I18N::translate('Fact 13')), + 'HEAD:_SCHEMA:INDI:_FA2' => new CustomElement(I18N::translate('Fact 2')), + 'HEAD:_SCHEMA:INDI:_FA3' => new CustomElement(I18N::translate('Fact 3')), + 'HEAD:_SCHEMA:INDI:_FA4' => new CustomElement(I18N::translate('Fact 4')), + 'HEAD:_SCHEMA:INDI:_FA5' => new CustomElement(I18N::translate('Fact 5')), + 'HEAD:_SCHEMA:INDI:_FA6' => new CustomElement(I18N::translate('Fact 6')), + 'HEAD:_SCHEMA:INDI:_FA7' => new CustomElement(I18N::translate('Fact 7')), + 'HEAD:_SCHEMA:INDI:_FA8' => new CustomElement(I18N::translate('Fact 8')), + 'HEAD:_SCHEMA:INDI:_FA9' => new CustomElement(I18N::translate('Fact 9')), + 'HEAD:_SCHEMA:INDI:_FREL' => new CustomElement('Relationship to father'), + 'HEAD:_SCHEMA:INDI:_M*:LABL' => new CustomElement(I18N::translate('Label')), + 'HEAD:_SCHEMA:INDI:_MREL' => new CustomElement('Relationship to mother'), + 'INDI:*:SOUR:_APID' => new CustomElement('Ancestry.com source identifier'), + 'INDI:*:SOUR:_LINK' => new CustomElement('External link'), + 'INDI:NAME:_AKA' => new NamePersonal(I18N::translate('Also known as'), []), + 'INDI:NAME:_MARNM' => new NamePersonal(I18N::translate('Married name'), []), + 'INDI:_CIRC' => new CustomElement('Circumcision'), + 'INDI:_DCAUSE' => new CustomElement(I18N::translate('Cause of death')), + 'INDI:_DEG' => new CustomElement(I18N::translate('Degree')), + 'INDI:_DNA' => new CustomElement(I18N::translate('DNA markers')), + 'INDI:_ELEC' => new CustomElement('Elected'), + 'INDI:_EMPLOY' => new CustomElement('Employment'), + 'INDI:_EXCM' => new CustomElement('Excommunicated'), + 'INDI:_FA1' => new CustomElement('Fact 1'), + 'INDI:_FA10' => new CustomElement('Fact 10'), + 'INDI:_FA11' => new CustomElement('Fact 11'), + 'INDI:_FA12' => new CustomElement('Fact 12'), + 'INDI:_FA13' => new CustomElement('Fact 13'), + 'INDI:_FA2' => new CustomElement('Fact 2'), + 'INDI:_FA3' => new CustomElement('Fact 3'), + 'INDI:_FA4' => new CustomElement('Fact 4'), + 'INDI:_FA5' => new CustomElement('Fact 5'), + 'INDI:_FA6' => new CustomElement('Fact 6'), + 'INDI:_FA7' => new CustomElement('Fact 7'), + 'INDI:_FA8' => new CustomElement('Fact 8'), + 'INDI:_FA9' => new CustomElement('Fact 9'), + 'INDI:_MDCL' => new CustomElement('Medical'), + 'INDI:_MILT' => new CustomElement(I18N::translate('Military service')), + 'INDI:_MILTID' => new CustomElement('Military ID number'), + 'INDI:_MISN' => new CustomElement('Mission'), + 'INDI:_NAMS' => new CustomElement(I18N::translate('Namesake')), + 'INDI:_UNKN' => new CustomElement(I18N::translate('Unknown')), // Special individual ID code for later file comparisons + // The context and meaning of these tags is unknown + '_FOOT' => new CustomElement(''), + '_FUN' => new CustomElement(''), + '_JUST' => new CustomElement(''), + '_PHOTO' => new CustomElement(''), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Family Tree Maker™'; + } +} diff --git a/app/Module/CustomTagsGedcom53.php b/app/Module/CustomTagsGedcom53.php new file mode 100644 index 0000000000..716f3b3536 --- /dev/null +++ b/app/Module/CustomTagsGedcom53.php @@ -0,0 +1,191 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CertaintyAssessment; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\DateValue; +use Fisharebest\Webtrees\Elements\NoteStructure; +use Fisharebest\Webtrees\Elements\PlaceName; +use Fisharebest\Webtrees\Elements\SourceMediaType; +use Fisharebest\Webtrees\Elements\TextFromSource; +use Fisharebest\Webtrees\Elements\XrefSource; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsGedcom53 + */ +class CustomTagsGedcom53 extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'EVEN' => new CustomElement('Event'), + 'EVEN:*:*:NAME' => new CustomElement(I18N::translate('Name')), + 'EVEN:*:AUDIO' => new CustomElement(I18N::translate('Audio')), + 'EVEN:*:BROT' => new PlaceName('Brother'), + 'EVEN:*:BUYR' => new PlaceName('Buyer'), + 'EVEN:*:CHIL' => new PlaceName('Child'), + 'EVEN:*:DATE' => new DateValue('Date'), + 'EVEN:*:FATH' => new PlaceName('Father'), + 'EVEN:*:GODP' => new PlaceName('Godparent'), + 'EVEN:*:HDOH' => new PlaceName('Head of household'), + 'EVEN:*:HEIR' => new PlaceName('Heir'), + 'EVEN:*:HFAT' => new PlaceName('Husband’s father'), + 'EVEN:*:HMOT' => new PlaceName('Husband’s mother'), + 'EVEN:*:HUSB' => new PlaceName('Husband'), + 'EVEN:*:IMAGE' => new CustomElement('Image'), + 'EVEN:*:INDI' => new PlaceName('Individual'), + 'EVEN:*:INFT' => new PlaceName('Informant'), + 'EVEN:*:LEGA' => new PlaceName('Legatee'), + 'EVEN:*:MBR' => new PlaceName('Member'), + 'EVEN:*:MOTH' => new PlaceName('Mother'), + 'EVEN:*:OFFI' => new PlaceName('Official'), + 'EVEN:*:PARE' => new PlaceName('Parent'), + 'EVEN:*:PHOTO' => new CustomElement(I18N::translate('Photo')), + 'EVEN:*:PHUS' => new PlaceName('Previous husband'), + 'EVEN:*:PLAC' => new PlaceName('Place'), + 'EVEN:*:PWIF' => new PlaceName('Previous wife'), + 'EVEN:*:RECO' => new PlaceName('Recorder'), + 'EVEN:*:REL' => new PlaceName('Relative'), + 'EVEN:*:SELR' => new PlaceName('Seller'), + 'EVEN:*:SIBL' => new PlaceName('Sibling'), + 'EVEN:*:SIST' => new PlaceName('Sister'), + 'EVEN:*:SPOU' => new PlaceName('Spouse'), + 'EVEN:*:TXPY' => new PlaceName('Taxpayer'), + 'EVEN:*:VIDEO' => new CustomElement(I18N::translate('Video')), + 'EVEN:*:WFAT' => new PlaceName('Wife’s father'), + 'EVEN:*:WIFE' => new PlaceName('Wife'), + 'EVEN:*:WITN' => new PlaceName('Witness'), + 'EVEN:*:WMOT' => new PlaceName('Wife’s mother'), + 'EVEN:TYPE' => new CustomElement('Type of event'), + 'FAM:*:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'FAM:*:PLAC:SITE' => new CustomElement('Site'), + 'FAM:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'FAM:AUDIO' => new CustomElement(I18N::translate('Audio')), + 'FAM:IMAGE' => new CustomElement('Image'), + 'FAM:PHOTO' => new CustomElement(I18N::translate('Photo')), + 'FAM:VIDEO' => new CustomElement(I18N::translate('Video')), + 'HEAD:SCHEMA' => new CustomElement(I18N::translate('Unknown')), + 'HEAD:SCHEMA:FAM' => new CustomElement(I18N::translate('Family')), + 'HEAD:SCHEMA:FAM:*:_*' => new CustomElement('Custom event'), + 'HEAD:SCHEMA:FAM:*:_*:DEFN' => new CustomElement('Definition'), + 'HEAD:SCHEMA:FAM:*:_*:ISA' => new CustomElement('Type of event'), + 'HEAD:SCHEMA:FAM:*:_*:LABL' => new CustomElement('Label'), + 'HEAD:SCHEMA:FAM:_*' => new CustomElement('Custom event'), + 'HEAD:SCHEMA:FAM:_*:DEFN' => new CustomElement('Definition'), + 'HEAD:SCHEMA:FAM:_*:ISA' => new CustomElement('Type of event'), + 'HEAD:SCHEMA:FAM:_*:LABL' => new CustomElement('Label'), + 'HEAD:SCHEMA:INDI' => new CustomElement(I18N::translate('Individual')), + 'HEAD:SCHEMA:INDI:*:_*' => new CustomElement('Custom event'), + 'HEAD:SCHEMA:INDI:*:_*:DEFN' => new CustomElement('Definition'), + 'HEAD:SCHEMA:INDI:*:_*:ISA' => new CustomElement('Type of event'), + 'HEAD:SCHEMA:INDI:*:_*:LABL' => new CustomElement('Label'), + 'HEAD:SCHEMA:INDI:_*' => new CustomElement('Custom event'), + 'HEAD:SCHEMA:INDI:_*:DEFN' => new CustomElement('Definition'), + 'HEAD:SCHEMA:INDI:_*:ISA' => new CustomElement('Type of event'), + 'HEAD:SCHEMA:INDI:_*:LABL' => new CustomElement('Label'), + 'INDI:*:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'INDI:*:PLAC:SITE' => new CustomElement('Site'), + 'INDI:*:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'INDI:AUDIO' => new CustomElement(I18N::translate('Audio')), + 'INDI:BURI:PLAC:CEME' => new CustomElement(I18N::translate('Cemetery')), + 'INDI:BURI:PLAC:CEME:PLOT' => new CustomElement('Burial plot'), + 'INDI:IMAGE' => new CustomElement('Image'), + 'INDI:NAMR' => new CustomElement(I18N::translate('Religious name')), + 'INDI:NAMS' => new CustomElement(I18N::translate('Namesake')), + 'INDI:PHOTO' => new CustomElement(I18N::translate('Photo')), + 'INDI:SIGN' => new CustomElement('Signature'), + 'INDI:VIDEO' => new CustomElement(I18N::translate('Video')), + 'REPO:CALN:ITEM' => new CustomElement('Item'), + 'REPO:CALN:PAGE' => new CustomElement('Page'), + 'REPO:CALN:SHEE' => new CustomElement('Sheet'), + 'REPO:CNTC' => new CustomElement('Contact person'), + 'REPO:MEDI' => new SourceMediaType(I18N::translate('Media type')), + 'REPO:REFN' => new CustomElement('Reference number'), + 'SOUR:AUDIO' => new CustomElement(I18N::translate('Audio')), + 'SOUR:CENS' => new CustomElement('Census'), + 'SOUR:CENS:DATE' => new CustomElement('Census'), + 'SOUR:CENS:DWEL' => new CustomElement('Dwelling number'), + 'SOUR:CENS:FAMN' => new CustomElement('Family number'), + 'SOUR:CENS:LINE' => new CustomElement('Line number'), + 'SOUR:CLAS' => new CustomElement('Source classification'), + 'SOUR:CPLR' => new CustomElement('Compiler'), + 'SOUR:EDTR' => new CustomElement('Editor'), + 'SOUR:EVEN' => new CustomElement('Source events'), + 'SOUR:FIDE' => new CustomElement('Fidelity'), + 'SOUR:FILM' => new CustomElement(I18N::translate('Microfilm')), + 'SOUR:IMAGE' => new CustomElement('Image'), + 'SOUR:INDX' => new CustomElement('Indexed'), + 'SOUR:INTV' => new CustomElement('Interviewer'), + 'SOUR:ORIG' => new CustomElement('Originator'), + 'SOUR:ORIG:NAME' => new CustomElement('Name'), + 'SOUR:ORIG:NOTE' => new CustomElement('Note'), + 'SOUR:ORIG:TYPE' => new CustomElement('Type'), + 'SOUR:PERI' => new CustomElement('Date period'), + 'SOUR:PHOTO' => new CustomElement(I18N::translate('Photo')), + 'SOUR:PUBL:DATE' => new CustomElement('Date'), + 'SOUR:PUBL:EDTN' => new CustomElement('Edition'), + 'SOUR:PUBL:ISSU' => new CustomElement('Issue'), + 'SOUR:PUBL:LCCN' => new CustomElement('Library of Congress call number'), + 'SOUR:PUBL:NAME' => new CustomElement('Name'), + 'SOUR:PUBL:PUBR' => new CustomElement('Publisher'), + 'SOUR:PUBL:SERS' => new CustomElement('Series'), + 'SOUR:PUBL:TYPE' => new CustomElement('Type'), + 'SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'SOUR:RECO' => new CustomElement('Recording agency?'), + 'SOUR:REFS' => new XrefSource('Referenced source'), + 'SOUR:REPO:DPRT:ARVL' => new CustomElement('Departure'), + 'SOUR:REPO:DPRT:ARVL:DATE' => new DateValue('Date'), + 'SOUR:REPO:DPRT:ARVL:PLAC' => new PlaceName('Place'), + 'SOUR:REPO:NAME' => new CustomElement('Name of vessel'), + 'SOUR:REPO:NOTE' => new NoteStructure(I18N::translate('Note')), + 'SOUR:REPO:PORT' => new CustomElement('Port'), + 'SOUR:REPO:PORT:ARVL' => new CustomElement('Arrival'), + 'SOUR:REPO:PORT:ARVL:DATE' => new DateValue('Date'), + 'SOUR:REPO:PORT:ARVL:PLAC' => new PlaceName('Place'), + 'SOUR:REPO:TEXT' => new TextFromSource(I18N::translate('Text')), + 'SOUR:SEQU' => new CustomElement('Sequence'), + 'SOUR:STAT' => new CustomElement('Search status'), + 'SOUR:STAT:DATE' => new DateValue('Date'), + 'SOUR:TEXT' => new TextFromSource(I18N::translate('Text')), + 'SOUR:TYPE' => new CustomElement('Type of source'), + 'SOUR:VIDEO' => new CustomElement(I18N::translate('Video')), + 'SOUR:XLTR' => new CustomElement('Translator'), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'GEDCOM 5.3'; + } +} diff --git a/app/Module/CustomTagsGedcom55.php b/app/Module/CustomTagsGedcom55.php new file mode 100644 index 0000000000..7e671e0fcf --- /dev/null +++ b/app/Module/CustomTagsGedcom55.php @@ -0,0 +1,53 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsGedcom55 + */ +class CustomTagsGedcom55 extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'OBJE:BLOB' => new CustomElement(I18N::translate('Binary data object')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'GEDCOM 5.5'; + } +} diff --git a/app/Module/CustomTagsGedcomL.php b/app/Module/CustomTagsGedcomL.php new file mode 100644 index 0000000000..eee0bdcb16 --- /dev/null +++ b/app/Module/CustomTagsGedcomL.php @@ -0,0 +1,248 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\AddressPostalCode; +use Fisharebest\Webtrees\Elements\CertaintyAssessment; +use Fisharebest\Webtrees\Elements\Change; +use Fisharebest\Webtrees\Elements\ChangeDate; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\DateValue; +use Fisharebest\Webtrees\Elements\EmptyElement; +use Fisharebest\Webtrees\Elements\EntryRecordingDate; +use Fisharebest\Webtrees\Elements\EventAttributeType; +use Fisharebest\Webtrees\Elements\EventDescriptor; +use Fisharebest\Webtrees\Elements\EventTypeCitedFrom; +use Fisharebest\Webtrees\Elements\FamilyStatusText; +use Fisharebest\Webtrees\Elements\GovIdentifier; +use Fisharebest\Webtrees\Elements\HierarchicalRelationship; +use Fisharebest\Webtrees\Elements\LanguageId; +use Fisharebest\Webtrees\Elements\LocationRecord; +use Fisharebest\Webtrees\Elements\MaidenheadLocator; +use Fisharebest\Webtrees\Elements\NamePieceGiven; +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\RelationIsDescriptor; +use Fisharebest\Webtrees\Elements\ReligiousAffiliation; +use Fisharebest\Webtrees\Elements\ResearchTask; +use Fisharebest\Webtrees\Elements\ResearchTaskPriority; +use Fisharebest\Webtrees\Elements\ResearchTaskStatus; +use Fisharebest\Webtrees\Elements\ResearchTaskType; +use Fisharebest\Webtrees\Elements\RoleInEvent; +use Fisharebest\Webtrees\Elements\SexXValue; +use Fisharebest\Webtrees\Elements\SourceData; +use Fisharebest\Webtrees\Elements\SubmitterText; +use Fisharebest\Webtrees\Elements\TextFromSource; +use Fisharebest\Webtrees\Elements\TimeValue; +use Fisharebest\Webtrees\Elements\WhereWithinSource; +use Fisharebest\Webtrees\Elements\XrefAssociate; +use Fisharebest\Webtrees\Elements\XrefLocation; +use Fisharebest\Webtrees\Elements\XrefMedia; +use Fisharebest\Webtrees\Elements\XrefRepository; +use Fisharebest\Webtrees\Elements\XrefSource; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsGedcomL + * + * @see https://genealogy.net/GEDCOM/GEDCOM551%20GEDCOM-L%20Addendum-R1.pdf + */ +class CustomTagsGedcomL extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'FAM:*:ADDR:_NAME' => new CustomElement('Name of addressee'), + 'FAM:*:PLAC:_GOV' => new GovIdentifier(I18N::translate('GOV identifier')), + 'FAM:*:PLAC:_LOC' => new XrefLocation(I18N::translate('Location')), + 'FAM:*:PLAC:_MAIDENHEAD' => new MaidenheadLocator('Maidenhead locator'), + 'FAM:*:PLAC:_POST' => new AddressPostalCode('Postal code'), + 'FAM:*:PLAC:_POST:DATE' => new DateValue(I18N::translate('Date')), + 'FAM:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), + 'FAM:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), + 'FAM:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), + 'FAM:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), + 'FAM:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), + 'FAM:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), + 'FAM:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), + 'FAM:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), + 'FAM:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), + 'FAM:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), + 'FAM:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), + 'FAM:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), + 'FAM:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'FAM:*:_WITN' => new CustomElement('Witness'), + 'FAM:_STAT' => new FamilyStatusText(I18N::translate('Family status')), + 'FAM:_TODO' => new ResearchTask(I18N::translate('Research task'), ['DESC' => '1:1', '_CAT' => '0:1', '_PRTY' => '0:1', 'TYPE' => '0:1', 'NOTE' => '0:M', 'DATA' => '0:1', 'STAT' => '0:1', '_CDATE' => '0:1', '_RDATE' => '0:1', 'REPO' => '0:1', '_UID' => '0:M']), + 'FAM:_TODO:DATA' => new SubmitterText(I18N::translate('The solution')), + 'FAM:_TODO:DATE' => new DateValue(I18N::translate('Creation date')), + 'FAM:_TODO:DESC' => new CustomElement(I18N::translate('Description')), + 'FAM:_TODO:NOTE' => new SubmitterText(I18N::translate('The problem')), + 'FAM:_TODO:REPO' => new XrefRepository('Repository', []), + 'FAM:_TODO:STAT' => new ResearchTaskStatus(I18N::translate('Status')), + 'FAM:_TODO:TYPE' => new ResearchTaskType(I18N::translate('Type of research task')), + 'FAM:_TODO:_CAT' => new CustomElement(I18N::translate('Category')), + 'FAM:_TODO:_CDATE' => new DateValue(I18N::translate('Completion date')), + 'FAM:_TODO:_PRTY' => new ResearchTaskPriority(I18N::translate('Priority')), + 'FAM:_TODO:_RDATE' => new DateValue(I18N::translate('Reminder date')), + 'FAM:_UID' => new PafUid(I18N::translate('Unique identifier')), + 'HEAD:SOUR:CORP:ADDR:_NAME' => new CustomElement('Name of addressee'), + 'HEAD:_SCHEMA' => new EmptyElement(I18N::translate('Schema')), + 'HEAD:_SCHEMA:*' => new EmptyElement(I18N::translate('Base GEDCOM tag')), + 'HEAD:_SCHEMA:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), + 'HEAD:_SCHEMA:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), + 'HEAD:_SCHEMA:*:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), + 'HEAD:_SCHEMA:*:*:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), + 'HEAD:_SCHEMA:*:*:*:*:*:*' => new EmptyElement(I18N::translate('New GEDCOM tag')), + 'HEAD:_SCHEMA:*:*:*:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), + 'HEAD:_SCHEMA:*:*:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), + 'HEAD:_SCHEMA:*:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), + 'HEAD:_SCHEMA:*:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), + 'HEAD:_SCHEMA:*:*:_DEFN' => new EmptyElement(I18N::translate('Definition')), + 'INDI:*:ADDR:_NAME' => new CustomElement('Name of addressee'), + 'INDI:*:PLAC:_GOV' => new GovIdentifier(I18N::translate('GOV identifier')), + 'INDI:*:PLAC:_LOC' => new XrefLocation(I18N::translate('Location')), + 'INDI:*:PLAC:_MAIDENHEAD' => new MaidenheadLocator('Maidenhead locator'), + 'INDI:*:PLAC:_POST' => new AddressPostalCode('Postal code'), + 'INDI:*:PLAC:_POST:DATE' => new DateValue(I18N::translate('Date')), + 'INDI:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), + 'INDI:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), + 'INDI:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), + 'INDI:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), + 'INDI:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), + 'INDI:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), + 'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), + 'INDI:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), + 'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), + 'INDI:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), + 'INDI:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), + 'INDI:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), + 'INDI:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'INDI:*:_WITN' => new CustomElement('Witness'), + 'INDI:BAPM:_GODP' => new CustomElement('Godparent'), + 'INDI:CHR:_GODP' => new CustomElement('Godparent'), + 'INDI:NAME:_RUFNAME' => new NamePieceGiven(I18N::translate('Rufname')), + 'INDI:OBJE:_PRIM' => new CustomElement(I18N::translate('Highlighted image')), + 'INDI:SEX' => new SexXValue(I18N::translate('Gender')), + 'INDI:_TODO' => new ResearchTask(I18N::translate('Research task')), + 'INDI:_TODO:DATA' => new SubmitterText(I18N::translate('The solution')), + 'INDI:_TODO:DATE' => new DateValue(I18N::translate('Creation date')), + 'INDI:_TODO:DESC' => new CustomElement(I18N::translate('Description')), + 'INDI:_TODO:NOTE' => new SubmitterText(I18N::translate('The problem')), + 'INDI:_TODO:REPO' => new XrefRepository('Repository', []), + 'INDI:_TODO:STAT' => new ResearchTaskStatus(I18N::translate('Status')), + 'INDI:_TODO:TYPE' => new ResearchTaskType(I18N::translate('Type of research task')), + 'INDI:_TODO:_CAT' => new CustomElement(I18N::translate('Category')), + 'INDI:_TODO:_CDATE' => new DateValue(I18N::translate('Completion date')), + 'INDI:_TODO:_PRTY' => new ResearchTaskPriority(I18N::translate('Priority')), + 'INDI:_TODO:_RDATE' => new DateValue(I18N::translate('Reminder date')), + 'INDI:_UID' => new PafUid(I18N::translate('Unique identifier')), + 'NOTE:_UID' => new PafUid(I18N::translate('Unique identifier')), + 'OBJE:FILE:_PRIM' => new CustomElement(I18N::translate('Highlighted image')), + 'OBJE:_UID' => new PafUid(I18N::translate('Unique identifier')), + 'REPO:ADDR:_NAME' => new CustomElement('Name of addressee'), + 'REPO:_UID' => new PafUid(I18N::translate('Unique identifier')), + 'SOUR:_UID' => new PafUid(I18N::translate('Unique identifier')), + 'SUBM:ADDR:_NAME' => new CustomElement('Name of addressee'), + 'SUBM:_UID' => new PafUid(I18N::translate('Unique identifier')), + 'SUBN:_UID' => new PafUid(I18N::translate('Unique identifier')), + '_LOC' => new LocationRecord(I18N::translate('Location')), + '_LOC:CHAN' => new Change(I18N::translate('Last change')), + '_LOC:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), + '_LOC:CHAN:DATE:TIME' => new TimeValue(I18N::translate('Time')), + '_LOC:CHAN:NOTE' => new NoteStructure(I18N::translate('Note')), + '_LOC:EVEN' => new EventDescriptor(I18N::translate('Event'), ['TYPE' => '0:1']), + '_LOC:EVEN:TYPE' => new EventAttributeType(I18N::translate('Type of event')), + '_LOC:MAP' => new EmptyElement(I18N::translate('Coordinates')), + '_LOC:MAP:LATI' => new PlaceLatitude(I18N::translate('Latitude')), + '_LOC:MAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude')), + '_LOC:NAME' => new PlaceName(I18N::translate('Place'), ['ABBR' => '0:1', 'DATE' => '0:1', 'LANG' => '0:1', 'SOUR' => '0:M']), + '_LOC:NAME:ABBR' => new CustomElement(I18N::translate('Abbreviation')), + '_LOC:NAME:ABBR:TYPE' => new CustomElement(I18N::translate('Type of abbreviation')), + '_LOC:NAME:DATE' => new DateValue(I18N::translate('Date')), + '_LOC:NAME:LANG' => new LanguageId(I18N::translate('Language')), + '_LOC:NAME:SOUR' => new XrefSource(I18N::translate('Source')), + '_LOC:NOTE' => new NoteStructure(I18N::translate('Note')), + '_LOC:OBJE' => new XrefMedia(I18N::translate('Media')), + '_LOC:RELI' => new ReligiousAffiliation('Religion', []), + '_LOC:SOUR' => new XrefSource(I18N::translate('Source')), + '_LOC:SOUR:DATA' => new SourceData(I18N::translate('Data')), + '_LOC:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), + '_LOC:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), + '_LOC:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), + '_LOC:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), + '_LOC:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), + '_LOC:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), + '_LOC:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), + '_LOC:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + '_LOC:TYPE' => new CustomElement(I18N::translate('Type of location')), + '_LOC:TYPE:DATE' => new DateValue(I18N::translate('Date')), + '_LOC:TYPE:SOUR' => new XrefSource(I18N::translate('Source')), + '_LOC:TYPE:_GOVTYPE' => new CustomElement('GOV identifier type'), + '_LOC:_AIDN' => new CustomElement('Administrative ID'), + '_LOC:_AIDN:DATE' => new DateValue(I18N::translate('Date')), + '_LOC:_AIDN:SOUR' => new XrefSource(I18N::translate('Source')), + '_LOC:_AIDN:TYPE' => new CustomElement(I18N::translate('Type of administrative ID')), + '_LOC:_DMGD' => new CustomElement('Demographic data'), + '_LOC:_DMGD:DATE' => new DateValue(I18N::translate('Date')), + '_LOC:_DMGD:SOUR' => new XrefSource(I18N::translate('Source')), + '_LOC:_DMGD:TYPE' => new CustomElement(I18N::translate('Type of demographic data')), + '_LOC:_GOV' => new GovIdentifier(I18N::translate('GOV identifier')), + '_LOC:_LOC' => new XrefLocation(I18N::translate('Parent'), ['DATE' => '0:1', 'SOUR' => '0:M', 'TYPE' => '0:1']), + '_LOC:_LOC:DATE' => new DateValue(I18N::translate('Date')), + '_LOC:_LOC:SOUR' => new XrefSource(I18N::translate('Source')), + '_LOC:_LOC:TYPE' => new HierarchicalRelationship(I18N::translate('Hierarchical relationship')), + '_LOC:_MAIDENHEAD' => new MaidenheadLocator('Maidenhead locator'), + '_LOC:_POST' => new AddressPostalCode(I18N::translate('Postal code')), + '_LOC:_POST:DATE' => new DateValue(I18N::translate('Date')), + '_LOC:_POST:SOUR' => new XrefSource(I18N::translate('Source')), + '_LOC:_UID' => new PafUid(I18N::translate('Unique identifier')), + '_LOC:*:SOUR:DATA' => new SourceData(I18N::translate('Data')), + '_LOC:*:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), + '_LOC:*:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), + '_LOC:*:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), + '_LOC:*:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), + '_LOC:*:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), + '_LOC:*:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), + '_LOC:*:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), + '_LOC:*:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'GEDCOM-L'; + } +} diff --git a/app/Module/CustomTagsLegacy.php b/app/Module/CustomTagsLegacy.php new file mode 100644 index 0000000000..b657d38291 --- /dev/null +++ b/app/Module/CustomTagsLegacy.php @@ -0,0 +1,138 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CustomElement; + +/** + * Class CustomTagsLegacy + */ +class CustomTagsLegacy extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @see http://support.legacyfamilytree.com/article/AA-00520/0/GEDCOM-Files-custom-tags-in-Legacy.html + * + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'FAM:*:ADDR:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), + 'FAM:*:PLAC:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), + 'FAM:*:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), + 'FAM:*:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), + 'FAM:CHIL:_FREL' => new CustomElement('The Relationship of a child to the Father (under a CHIL block under a FAM record).'), + 'FAM:CHIL:_MREL' => new CustomElement('The Relationship of a child to the Mother (under a CHIL block under a FAM record).'), + 'FAM:CHIL:_STAT' => new CustomElement('The Status of a marriage (Married, Unmarried, etc.). Also the Status of a child (Twin, Triplet, etc.). (The marriage status of Divorced is exported using a DIV tag.)'), + 'FAM:EVEN:_OVER' => new CustomElement('An event sentence override (under an EVEN block).'), + 'FAM:MARR:_STAT' => new CustomElement('The Status of a marriage (Married, Unmarried, etc.). Also the Status of a child (Twin, Triplet, etc.). (The marriage status of Divorced is exported using a DIV tag.)'), + 'FAM:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), + 'FAM:_NONE' => new CustomElement('Indicates that a couple had no children (under a FAM record).'), + 'HEAD:_EVENT_DEFN' => new CustomElement('Indicates the start of an Event Definition record that describes the attributes of an event or fact.'), + 'HEAD:_EVENT_DEFN:_CONF_FLAG' => new CustomElement('Indicates that an event is Confidential or Private (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_DATE_TYPE' => new CustomElement('Indicates whether or not a Date field is shown for a specific event (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_DESC_FLAG' => new CustomElement('Indicates whether or not a Description field is shown for a specific event (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_PLACE_TYPE' => new CustomElement('Indicates whether or not a Place field is shown for a specific event (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_PP_EXCLUDE' => new CustomElement('Indicates that an event is to be Excluded from the Potential Problems reporting (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN1' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN2' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN3' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN4' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN5' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN6' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN7' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SEN8' => new CustomElement('Event sentence definitions (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENDOF' => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENDOM' => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENDOU' => new CustomElement('Event sentence for PAF5 if only the Date field is filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENDPF' => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENDPM' => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENDPU' => new CustomElement('Event sentence for PAF5 if only the Date and Place fields are filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENF' => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENM' => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENPOF' => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENPOM' => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENPOU' => new CustomElement('Event sentence for PAF5 if only the Place field is filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_EVENT_DEFN:_SENU' => new CustomElement('Event sentence for PAF5 if all fields are filled in for a Male individual (under an _EVENT_DEFN record).'), + 'HEAD:_PLAC_DEFN' => new CustomElement('Indicates the start of a Place Definition record that describes the attribute of a place.'), + 'HEAD:_PLAC_DEFN:_PREP' => new CustomElement('A location Preposition (under a _PLAC_DEFN record).'), + 'INDI:*:ADDR:_LIST3 YES' => new CustomElement('Indicates that a person’s address is part of the Birthday grouping (under an ADDR block).'), + 'INDI:*:ADDR:_LIST4 YES' => new CustomElement('Indicates that a person’s address is part of the Research grouping (under an ADDR block).'), + 'INDI:*:ADDR:_LIST5 YES' => new CustomElement('Indicates that a person’s address is part of the Christmas grouping (under an ADDR block).'), + 'INDI:*:ADDR:_LIST6 YES' => new CustomElement('Indicates that a person’s address is part of the Holiday grouping (under an ADDR block).'), + 'INDI:*:ADDR:_NAME' => new CustomElement('The name of an individual as part of an address (under an ADDR block).'), + 'INDI:*:ADDR:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), + 'INDI:*:ADDR:_SORT' => new CustomElement('The spelling of a name to be used when sorting addresses for a report (under an ADDR block).'), + 'INDI:*:ADDR:_TAG' => new CustomElement('Indicates that an address, or place has been tagged. Also used for Tag 1 selection for an individual.'), + 'INDI:*:PLAC:_TAG' => new CustomElement('Indicates that an address, or place has been tagged. Also used for Tag 1 selection for an individual.'), + 'INDI:*:PLAC:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), + 'INDI:*:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), + 'INDI:*:_PRIV' => new CustomElement('Indicates that an address or event is marked as Private.'), + 'INDI:ADDR:_EMAIL' => new CustomElement('An email address (under an ADDR block).'), + 'INDI:ADDR:_LIST1 YES' => new CustomElement('Indicates that a person’s address is part of the Newsletter grouping (under an ADDR block).'), + 'INDI:ADDR:_LIST2 YES' => new CustomElement('Indicates that a person’s address is part of the Family Association grouping (under an ADDR block).'), + 'INDI:EVEN:_OVER' => new CustomElement('An event sentence override (under an EVEN block).'), + 'INDI:SOUR:_VERI' => new CustomElement('Indicates that a source citation or place name has a checkmark in the Verified column.'), + 'INDI:_TAG' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG2' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG3' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG4' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG5' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG6' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG7' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG8' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TAG9' => new CustomElement('When under an INDI record, indicates that an individual has been given certain tag marks.'), + 'INDI:_TODO' => new CustomElement('Research task'), + 'INDI:_TODO:_CAT' => new CustomElement('The Category of a To-Do item (under a _TODO record).'), + 'INDI:_TODO:_CDATE' => new CustomElement('Closed Date of a To-Do item (under a _TODO record).'), + 'INDI:_TODO:_LOCL' => new CustomElement('The Locality of a To-Do item (under a _TODO record).'), + 'INDI:_TODO:_RDATE' => new CustomElement('Reminder date on to-do items. (Under a _TODO record.)'), + 'INDI:_UID' => new CustomElement('A Unique Identification Number given to each individual in a family file.'), + 'INDI:_URL' => new CustomElement('An Internet address (under an INDI record).'), + 'OBJE:_DATE' => new CustomElement('A date associated with a multimedia object, usually a picture or video (under an OBJE block).'), + 'OBJE:_PRIM' => new CustomElement('Means a multimedia object, usually a picture, is the Primary object (the one that is shown on a report) (under an OBJE block).'), + 'OBJE:_SCBK' => new CustomElement('Indicates that a Picture is tagged to be included in a scrapbook report (under an OBJE block).'), + 'OBJE:_SOUND' => new CustomElement('A sound file name that is attached to a picture (under an OBJE block).'), + 'OBJE:_TYPE' => new CustomElement('The type of a multimedia object: Photo, Sound, or Video (under an OBJE block).'), + 'SOUR:_ITALIC Y' => new CustomElement('Indicates that a source title should be printed on a report in italics (under a SOUR record).'), + 'SOUR:_PAREN' => new CustomElement('Indicates that the Publication Facts of a source should be printed within parentheses on a report (under a SOUR record).'), + 'SOUR:_QUOTED Y' => new CustomElement('Indicates that a source title should be printed within quotes on a report (under a SOUR record).'), + 'SOUR:_TAG NO' => new CustomElement('When used under a SOUR record, indicates to exclude the source citation detail on reports.'), + 'SOUR:_TAG2 NO' => new CustomElement('When used under a SOUR record, indicates to exclude the source citation on reports.'), + 'SOUR:_TAG3 YES' => new CustomElement('When used under a SOUR record, indicates to include the source citation detail text on reports.'), + 'SOUR:_TAG4 YES' => new CustomElement('When used under a SOUR record, indicates to include the source citation detail notes on reports.'), + '_PREF' => new CustomElement('Indicates a Preferred spouse, child or parents.'), // How is this used? + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Legacy™'; + } +} diff --git a/app/Module/CustomTagsPersonalAncestralFile.php b/app/Module/CustomTagsPersonalAncestralFile.php new file mode 100644 index 0000000000..28827c3f39 --- /dev/null +++ b/app/Module/CustomTagsPersonalAncestralFile.php @@ -0,0 +1,67 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\AddressEmail; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\NamePersonal; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsPersonalAncestralFile + */ +class CustomTagsPersonalAncestralFile extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + * + * @see http://wiki-de.genealogy.net/GEDCOM/_Nutzerdef-Tag + */ + public function customTags(): array + { + return [ + 'INDI:NAME:_ADPN' => new NamePersonal(I18N::translate('Adopted name'), []), + 'INDI:NAME:_AKA' => new NamePersonal(I18N::translate('Also known as'), []), + 'INDI:NAME:_AKAN' => new NamePersonal(I18N::translate('Also known as'), []), + 'INDI:_EMAIL' => new AddressEmail(I18N::translate('Email address')), + 'URL' => new CustomElement(I18N::translate('URL')), + '_HEB' => new CustomElement(I18N::translate('Hebrew')), + '_NAME' => new CustomElement(I18N::translate('Mailing name')), + '_SCBK' => new CustomElement(I18N::translate('Scrapbook')), + '_SSHOW' => new CustomElement(I18N::translate('Slide show')), + '_TYPE' => new CustomElement(I18N::translate('Media type')), + '_URL' => new CustomElement(I18N::translate('URL')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Personal Ancestral File™'; + } +} diff --git a/app/Module/CustomTagsPhpGedView.php b/app/Module/CustomTagsPhpGedView.php new file mode 100644 index 0000000000..e71f38ae3f --- /dev/null +++ b/app/Module/CustomTagsPhpGedView.php @@ -0,0 +1,95 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\AddressEmail; +use Fisharebest\Webtrees\Elements\AddressLine; +use Fisharebest\Webtrees\Elements\AddressWebPage; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\Elements\CustomEvent; +use Fisharebest\Webtrees\Elements\NamePersonal; +use Fisharebest\Webtrees\Elements\NoteStructure; +use Fisharebest\Webtrees\Elements\RelationIsDescriptor; +use Fisharebest\Webtrees\Elements\RestrictionNotice; +use Fisharebest\Webtrees\Elements\TimeValue; +use Fisharebest\Webtrees\Elements\WebtreesUser; +use Fisharebest\Webtrees\Elements\XrefAssociate; +use Fisharebest\Webtrees\Elements\XrefMedia; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsPhpGedView + */ +class CustomTagsPhpGedView extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'FAM:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), + 'FAM:COMM' => new CustomElement(I18N::translate('Comment')), + 'INDI:*:ASSO' => new XrefAssociate(I18N::translate('Associate')), + 'INDI:*:ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), + 'INDI:*:PLAC:_HEB' => new NoteStructure(I18N::translate('Place in Hebrew')), + 'INDI:ADDR' => new AddressLine(I18N::translate('Address')), + 'INDI:BIRT:DATE:TIME' => new TimeValue(I18N::translate('Time')), + 'INDI:BURI:CEME' => new CustomElement(I18N::translate('Cemetery')), + 'INDI:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), + 'INDI:COMM' => new CustomElement(I18N::translate('Comment')), + 'INDI:DEAT:DATE:TIME' => new TimeValue(I18N::translate('Time')), + 'INDI:EMAIL' => new AddressEmail(I18N::translate('Email address')), + 'INDI:NAME:_HEB' => new NamePersonal(I18N::translate('Name in Hebrew'), []), + 'INDI:_FNRL' => new CustomEvent(I18N::translate('Funeral')), + 'INDI:_HOL' => new CustomEvent(I18N::translate('Holocaust')), + 'INDI:_MILI' => new CustomEvent(I18N::translate('Military')), + 'INDI:_PGV_OBJS' => new XrefMedia(I18N::translate('Re-order media')), + 'NOTE:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), + 'OBJE:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), + 'OBJE:_PRIM' => new CustomElement(I18N::translate('Highlighted image')), + 'OBJE:_THUM' => new CustomElement(I18N::translate('Thumbnail image')), + 'REPO:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), + 'SOUR:CHAN:_PGVU' => new WebtreesUser(I18N::translate('Author of last change')), + 'SOUR:SERV' => new CustomElement(I18N::translate('Remote server')), + 'SOUR:URL' => new AddressWebPage(I18N::translate('URL')), + 'SOUR:URL:TYPE' => new CustomElement(I18N::translate('Type')), // e.g. "FamilySearch" + 'SOUR:URL:_BLOCK' => new CustomElement(I18N::translate('Block')), // "e.g. "false" + 'SOUR:_DBID' => new CustomElement(I18N::translate('Database name')), + 'SOUR:_DBID:_PASS' => new CustomElement(I18N::translate('Database password')), + 'SOUR:_DBID:_PASS:RESN' => new RestrictionNotice(I18N::translate('Restriction')), + 'SOUR:_DBID:_USER' => new CustomElement(I18N::translate('Database user account')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'PhpGedView™'; + } +} diff --git a/app/Module/CustomTagsReunion.php b/app/Module/CustomTagsReunion.php new file mode 100644 index 0000000000..355ec70693 --- /dev/null +++ b/app/Module/CustomTagsReunion.php @@ -0,0 +1,59 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\AddressEmail; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsReunion + */ +class CustomTagsReunion extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'INDI:EMAL' => new AddressEmail(I18N::translate('Email address')), + 'INDI:CITN' => new CustomElement(I18N::translate('Citizenship')), + 'INDI:_LEGA' => new CustomElement(I18N::translate('Legatee')), + 'INDI:_MDCL' => new CustomElement(I18N::translate('Medical')), + 'INDI:_PURC' => new CustomElement('Land purchase'), + 'INDI:_SALE' => new CustomElement('Land sale'), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Reunion™'; + } +} diff --git a/app/Module/CustomTagsRootsMagic.php b/app/Module/CustomTagsRootsMagic.php new file mode 100644 index 0000000000..cbc96d0219 --- /dev/null +++ b/app/Module/CustomTagsRootsMagic.php @@ -0,0 +1,59 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\AddressWebPage; +use Fisharebest\Webtrees\Elements\CustomElement; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsRootsMagic + */ +class CustomTagsRootsMagic extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'INDI:_DNA' => new CustomElement(I18N::translate('DNA markers')), + 'INDI:_WEBTAG' => new CustomElement(I18N::translate('External link')), + 'INDI:_WEBTAG:NAME' => new CustomElement(I18N::translate('Text')), + 'INDI:_WEBTAG:URL' => new AddressWebPage(I18N::translate('URL')), + 'SOUR:_BIBL' => new CustomElement(I18N::translate('Bibliography')), + 'SOUR:_SUBQ' => new CustomElement(I18N::translate('Abbreviation')), + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'Roots Magic™'; + } +} diff --git a/app/Module/CustomTagsWebtrees.php b/app/Module/CustomTagsWebtrees.php new file mode 100644 index 0000000000..7c98982690 --- /dev/null +++ b/app/Module/CustomTagsWebtrees.php @@ -0,0 +1,124 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Elements\CertaintyAssessment; +use Fisharebest\Webtrees\Elements\EntryRecordingDate; +use Fisharebest\Webtrees\Elements\EventTypeCitedFrom; +use Fisharebest\Webtrees\Elements\NoteStructure; +use Fisharebest\Webtrees\Elements\RelationIsDescriptor; +use Fisharebest\Webtrees\Elements\RestrictionNotice; +use Fisharebest\Webtrees\Elements\RoleInEvent; +use Fisharebest\Webtrees\Elements\SourceData; +use Fisharebest\Webtrees\Elements\TextFromSource; +use Fisharebest\Webtrees\Elements\WebtreesUser; +use Fisharebest\Webtrees\Elements\WhereWithinSource; +use Fisharebest\Webtrees\Elements\XrefAssociate; +use Fisharebest\Webtrees\Elements\XrefMedia; +use Fisharebest\Webtrees\Elements\XrefSource; +use Fisharebest\Webtrees\I18N; + +/** + * Class CustomTagsWebtrees + */ +class CustomTagsWebtrees extends AbstractModule implements ModuleConfigInterface, ModuleCustomTagsInterface +{ + use ModuleConfigTrait; + use ModuleCustomTagsTrait; + + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return [ + 'FAM:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + 'FAM:_ASSO' => new XrefAssociate(I18N::translate('Associate')), + 'FAM:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), + 'FAM:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), + 'FAM:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), + 'FAM:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), + 'FAM:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), + 'FAM:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), + 'FAM:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), + 'FAM:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), + 'FAM:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), + 'FAM:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), + 'FAM:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), + 'FAM:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), + 'FAM:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), + 'FAM:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'INDI:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + 'INDI:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), + 'INDI:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note')), + 'INDI:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), + 'INDI:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), + 'INDI:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), + 'INDI:*:_ASSO:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')), + 'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), + 'INDI:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), + 'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), + 'INDI:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note')), + 'INDI:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), + 'INDI:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), + 'INDI:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), + 'NOTE:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + 'NOTE:RESN' => new RestrictionNotice(I18N::translate('Restriction')), + 'OBJE:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + 'OBJE:RESN' => new RestrictionNotice(I18N::translate('Restriction')), + 'REPO:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + 'REPO:RESN' => new RestrictionNotice(I18N::translate('Restriction')), + 'SOUR:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + 'SOUR:RESN' => new RestrictionNotice(I18N::translate('Restriction')), + 'SUBM:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + 'SUBM:RESN' => new RestrictionNotice(I18N::translate('Restriction')), + '_LOC:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), + '_LOC:RESN' => new RestrictionNotice(I18N::translate('Restriction')), + ]; + } + + /** + * @return array<array<string>> + */ + + public function customSubTags(): array + { + return [ + ['FAM:CHAN', '_WT_USER', '0:1', ''], + ['INDI:CHAN', '_WT_USER', '0:1', ''], + ['NOTE:CHAN', '_WT_USER', '0:1', ''], + ['OBJE:CHAN', '_WT_USER', '0:1', ''], + ['REPO:CHAN', '_WT_USER', '0:1', ''], + ['SOUR:CHAN', '_WT_USER', '0:1', ''], + ['SUBM:CHAN', '_WT_USER', '0:1', ''], + ]; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return 'webtrees™'; + } +} diff --git a/app/Module/ModuleCustomTagsInterface.php b/app/Module/ModuleCustomTagsInterface.php new file mode 100644 index 0000000000..36593bf7cf --- /dev/null +++ b/app/Module/ModuleCustomTagsInterface.php @@ -0,0 +1,45 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; + +/** + * Interface ModuleCustomTagsInterface + */ +interface ModuleCustomTagsInterface extends ModuleInterface +{ + /** + * @return array<string,ElementInterface> + */ + public function customTags(): array; + + /** + * @return array<array<string>> + */ + public function customSubTags(): array; + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string; +} diff --git a/app/Module/ModuleCustomTagsTrait.php b/app/Module/ModuleCustomTagsTrait.php new file mode 100644 index 0000000000..1c8b44bd97 --- /dev/null +++ b/app/Module/ModuleCustomTagsTrait.php @@ -0,0 +1,113 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Module; + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Http\ViewResponseTrait; +use Fisharebest\Webtrees\I18N; +use Fisharebest\Webtrees\Registry; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; + +/** + * Trait ModuleCustomTagsTrait + */ +trait ModuleCustomTagsTrait +{ + use ViewResponseTrait; + + public function boot(): void + { + $element_factory = Registry::elementFactory(); + $element_factory->register($this->customTags()); + + foreach ($this->customSubTags() as $subtags) { + [$tag, $subtag, $repeat, $before] = $subtags; + + $element_factory->make($tag)->subtag($subtag, $repeat, $before); + } + } + + /** + * How should this module be identified in the control panel, etc.? + * + * @return string + */ + public function title(): string + { + /* I18N: Name of a module */ + return I18N::translate('Custom tags') . ' — ' . $this->customTagApplication(); + } + + /** + * A sentence describing what this module does. + * + * @return string + */ + public function description(): string + { + /* I18N: Description of the “Custom tags” module */ + return I18N::translate('Support for non-standard GEDCOM tags.') . ' — ' . $this->customTagApplication(); + } + + /** + * @see https://www.gencom.org.nz/GEDCOM_tags.html + * + * @return array<string,ElementInterface> + */ + public function customTags(): array + { + return []; + } + + /** + * @return array<array<string>> + */ + public function customSubTags(): array + { + return []; + } + + /** + * The application for which we are supporting custom tags. + * + * @return string + */ + public function customTagApplication(): string + { + return ''; + } + + + /** + * @param ServerRequestInterface $request + * + * @return ResponseInterface + */ + public function getAdminAction(ServerRequestInterface $request): ResponseInterface + { + $this->layout = 'layouts/administration'; + + return $this->viewResponse('modules/custom-tags/config', [ + 'tags' => $this->customTags(), + 'title' => $this->title(), + ]); + } +} diff --git a/app/Services/ModuleService.php b/app/Services/ModuleService.php index d042c0c4c1..259c9794f5 100644 --- a/app/Services/ModuleService.php +++ b/app/Services/ModuleService.php @@ -49,6 +49,19 @@ use Fisharebest\Webtrees\Module\ColorsTheme; use Fisharebest\Webtrees\Module\CompactTreeChartModule; use Fisharebest\Webtrees\Module\ContactsFooterModule; use Fisharebest\Webtrees\Module\CustomCssJsModule; +use Fisharebest\Webtrees\Module\CustomTagsAldfaer; +use Fisharebest\Webtrees\Module\CustomTagsBrothersKeeper; +use Fisharebest\Webtrees\Module\CustomTagsFamilyTreeBuilder; +use Fisharebest\Webtrees\Module\CustomTagsFamilyTreeMaker; +use Fisharebest\Webtrees\Module\CustomTagsGedcom53; +use Fisharebest\Webtrees\Module\CustomTagsGedcom55; +use Fisharebest\Webtrees\Module\CustomTagsGedcomL; +use Fisharebest\Webtrees\Module\CustomTagsLegacy; +use Fisharebest\Webtrees\Module\CustomTagsPersonalAncestralFile; +use Fisharebest\Webtrees\Module\CustomTagsPhpGedView; +use Fisharebest\Webtrees\Module\CustomTagsReunion; +use Fisharebest\Webtrees\Module\CustomTagsRootsMagic; +use Fisharebest\Webtrees\Module\CustomTagsWebtrees; use Fisharebest\Webtrees\Module\CzechMonarchsAndPresidents; use Fisharebest\Webtrees\Module\DeathReportModule; use Fisharebest\Webtrees\Module\DescendancyChartModule; @@ -188,6 +201,7 @@ use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface; use Fisharebest\Webtrees\Module\ModuleBlockInterface; use Fisharebest\Webtrees\Module\ModuleChartInterface; use Fisharebest\Webtrees\Module\ModuleCustomInterface; +use Fisharebest\Webtrees\Module\ModuleCustomTagsInterface; use Fisharebest\Webtrees\Module\ModuleDataFixInterface; use Fisharebest\Webtrees\Module\ModuleFooterInterface; use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface; @@ -273,6 +287,7 @@ class ModuleService ModuleAnalyticsInterface::class, ModuleBlockInterface::class, ModuleChartInterface::class, + ModuleCustomTagsInterface::class, ModuleDataFixInterface::class, ModuleFooterInterface::class, ModuleHistoricEventsInterface::class, @@ -337,6 +352,19 @@ class ModuleService 'contact-links' => ContactsFooterModule::class, 'czech-leaders' => CzechMonarchsAndPresidents::class, 'custom-css-js' => CustomCssJsModule::class, + 'custom-tags-aldfaer' => CustomTagsAldfaer::class, + 'custom-tags-bk' => CustomTagsBrothersKeeper::class, + 'custom-tags-gedcom-53' => CustomTagsGedcom53::class, + 'custom-tags-gedcom-55' => CustomTagsGedcom55::class, + 'custom-tags-gedcom-l' => CustomTagsGedcomL::class, + 'custom-tags-legacy' => CustomTagsLegacy::class, + 'custom-tags-ftb' => CustomTagsFamilyTreeBuilder::class, + 'custom-tags-ftm' => CustomTagsFamilyTreeMaker::class, + 'custom-tags-paf' => CustomTagsPersonalAncestralFile::class, + 'custom-tags-phpgedview' => CustomTagsPhpGedView::class, + 'custom-tags-reunion' => CustomTagsReunion::class, + 'custom-tags-roots-magic' => CustomTagsRootsMagic::class, + 'custom-tags-webtrees' => CustomTagsWebtrees::class, 'death_report' => DeathReportModule::class, 'descendancy' => DescendancyModule::class, 'descendancy_chart' => DescendancyChartModule::class, diff --git a/resources/views/admin/control-panel.phtml b/resources/views/admin/control-panel.phtml index d36563d594..a36faf3b6e 100644 --- a/resources/views/admin/control-panel.phtml +++ b/resources/views/admin/control-panel.phtml @@ -15,6 +15,7 @@ use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAllPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAnalyticsPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesBlocksPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesChartsPage; +use Fisharebest\Webtrees\Http\RequestHandlers\ModulesCustomTagsPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesDataFixesPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesFootersPage; use Fisharebest\Webtrees\Http\RequestHandlers\ModulesHistoricEventsPage; @@ -52,6 +53,7 @@ use Fisharebest\Webtrees\Module\ModuleBlockInterface; use Fisharebest\Webtrees\Module\ModuleChartInterface; use Fisharebest\Webtrees\Module\ModuleConfigInterface; use Fisharebest\Webtrees\Module\ModuleCustomInterface; +use Fisharebest\Webtrees\Module\ModuleCustomTagsInterface; use Fisharebest\Webtrees\Module\ModuleDataFixInterface; use Fisharebest\Webtrees\Module\ModuleFooterInterface; use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface; @@ -91,6 +93,8 @@ use Illuminate\Support\Collection; * @var Collection<ModuleChartInterface> $chart_modules_disabled * @var Collection<ModuleChartInterface> $chart_modules_enabled * @var Collection<ModuleCustomInterface> $custom_updates +* @var Collection<ModuleCustomTagsInterface> $custom_tags_modules_disabled + * @var Collection<ModuleCustomTagsInterface> $custom_tags_modules_enabled * @var Collection<ModuleDataFixInterface> $data_fix_modules_disabled * @var Collection<ModuleDataFixInterface> $data_fix_modules_enabled * @var Collection<string,int> $families @@ -684,6 +688,13 @@ use Illuminate\Support\Collection; </a> <?= view('components/badge', ['count' => $data_fix_modules_enabled->count(), 'total' => $data_fix_modules_disabled->count(), 'context' => 'primary']) ?> </li> + <li> + <span class="fa-li"><?= view('icons/tag') ?></span> + <a href="<?= e(route(ModulesCustomTagsPage::class)) ?>"> + <?= I18N::translate('Custom tags') ?> + </a> + <?= view('components/badge', ['count' => $custom_tags_modules_enabled->count(), 'total' => $custom_tags_modules_disabled->count(), 'context' => 'primary']) ?> + </li> </ul> <h3> diff --git a/resources/views/edit/edit-fact.phtml b/resources/views/edit/edit-fact.phtml index c6339bcef6..fc1350343c 100644 --- a/resources/views/edit/edit-fact.phtml +++ b/resources/views/edit/edit-fact.phtml @@ -106,24 +106,13 @@ use Ramsey\Uuid\Uuid; ?> <div class="form-group row"> - <label class="col-sm-3 col-form-label" for="keep_chan"> - <?= I18N::translate('Last change') ?> - </label> - <div class="col-sm-9"> - <?= view('components/checkbox-inline', ['label' => I18N::translate('Keep the existing “last change” information'), 'name' => 'keep_chan', 'checked' => (bool) $tree->getPreference('NO_UPDATE_CHAN')]) ?> - <div> - <?= I18N::translate('%1$s: %2$s', I18N::translate('Timestamp'), view('components/datetime', ['timestamp' => $fact->record()->lastChangeTimestamp()])) ?> - </div> - <div> - <?= I18N::translate('%1$s: %2$s', I18N::translate('Author of last change'), e($fact->record()->lastChangeUser())) ?> - </div> - </div> - </div> - - <div class="form-group row"> <div class="col-sm-3 wt-page-options-label"> </div> <div class="col-sm-9 wt-page-options-value"> + <div class="form-group"> + <?= view('components/checkbox', ['label' => I18N::translate('Keep the existing “last change” information'), 'name' => 'keep_chan', 'checked' => (bool) $tree->getPreference('NO_UPDATE_CHAN')]) ?> + </div> + <button class="btn btn-primary" type="submit"> <?= view('icons/save') ?> <?= /* I18N: A button label. */ diff --git a/resources/views/edit/edit-gedcom-fields.phtml b/resources/views/edit/edit-gedcom-fields.phtml index 4c6fafbb07..1e58a51d3a 100644 --- a/resources/views/edit/edit-gedcom-fields.phtml +++ b/resources/views/edit/edit-gedcom-fields.phtml @@ -12,6 +12,7 @@ use Ramsey\Uuid\Uuid; */ $gedcom = preg_replace('/\n\d CONT ?/', "\r", $gedcom); + ?> <?php foreach (explode("\n", $gedcom) as $line) : ?> @@ -26,6 +27,7 @@ $gedcom = preg_replace('/\n\d CONT ?/', "\r", $gedcom); <div class="form-group row"> <label class="col-sm-3 col-form-label" for="<?= e($id) ?>"> + <?= str_repeat(' ', max(0, $level -1)) ?> <?= $element->label() ?> </label> diff --git a/resources/views/edit/edit-record.phtml b/resources/views/edit/edit-record.phtml index 7070641203..9a6fa767f2 100644 --- a/resources/views/edit/edit-record.phtml +++ b/resources/views/edit/edit-record.phtml @@ -23,27 +23,16 @@ use Fisharebest\Webtrees\Tree; <?= view('edit/edit-gedcom-fields', ['gedcom' => $record->insertMissingSubtags(), 'hierarchy' => [$record->tag()], 'tree' => $tree, 'prefix' => '']) ?> - <?php if ($has_chan): ?> - <div class="form-group row"> - <label class="col-sm-3 col-form-label" for="keep_chan"> - <?= I18N::translate('Last change') ?> - </label> - <div class="col-sm-9"> - <?= view('components/checkbox-inline', ['label' => I18N::translate('Keep the existing “last change” information'), 'name' => 'keep_chan', 'checked' => (bool) $tree->getPreference('NO_UPDATE_CHAN')]) ?> - <div> - <?= I18N::translate('%1$s: %2$s', I18N::translate('Timestamp'), view('components/datetime', ['timestamp' => $record->lastChangeTimestamp()])) ?> - </div> - <div> - <?= I18N::translate('%1$s: %2$s', I18N::translate('Author of last change'), e($record->lastChangeUser())) ?> - </div> - </div> - </div> - <?php endif ?> - <div class="form-group row"> <div class="col-sm-3 wt-page-options-label"> </div> <div class="col-sm-9 wt-page-options-value"> + <?php if ($has_chan): ?> + <div class="form-group"> + <?= view('components/checkbox', ['label' => I18N::translate('Keep the existing “last change” information'), 'name' => 'keep_chan', 'checked' => (bool) $tree->getPreference('NO_UPDATE_CHAN')]) ?> + </div> + <?php endif ?> + <button class="btn btn-primary" type="submit"> <?= view('icons/save') ?> <?= /* I18N: A button label. */ diff --git a/resources/views/modules/custom-tags/config.phtml b/resources/views/modules/custom-tags/config.phtml new file mode 100644 index 0000000000..905a75198f --- /dev/null +++ b/resources/views/modules/custom-tags/config.phtml @@ -0,0 +1,42 @@ +<?php + +use Fisharebest\Webtrees\Contracts\ElementInterface; +use Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel; +use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAllPage; +use Fisharebest\Webtrees\I18N; + +/** + * @var array<string,ElementInterface> $tags + * @var string $title + */ + +?> + +<?= view('components/breadcrumbs', ['links' => [route(ControlPanel::class) => I18N::translate('Control panel'), route(ModulesAllPage::class) => I18N::translate('Modules'), $title]]) ?> + +<h1><?= $title ?></h1> + +<table class="table table-bordered"> + <caption class="sr-only"><?= I18N::translate('Custom tags') ?></caption> + <thead> + <tr> + <th><?= I18N::translate('Custom tag') ?></th> + <th><?= I18N::translate('Label') ?></th> + </tr> + </thead> + <tbody> + <?php foreach ($tags as $tag => $element) : ?> + <tr> + <td><code><?= $tag ?></code></td> + <td><?= $element->label() ?></td> + </tr> + <?php endforeach ?> + </tbody> +</table> + +<p> + <a href="<?= e(route(ControlPanel::class)) ?>" class="btn btn-primary"> + <?= view('icons/save') ?> + <?= I18N::translate('continue') ?> + </a> +</p> diff --git a/resources/views/repository-page-menu.phtml b/resources/views/repository-page-menu.phtml index d875725b57..014e450ef3 100644 --- a/resources/views/repository-page-menu.phtml +++ b/resources/views/repository-page-menu.phtml @@ -1,8 +1,7 @@ <?php -use Fisharebest\Webtrees\Auth; use Fisharebest\Webtrees\Http\RequestHandlers\DeleteRecord; -use Fisharebest\Webtrees\Http\RequestHandlers\EditRawRecordPage; +use Fisharebest\Webtrees\Http\RequestHandlers\EditRecordPage; use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Repository; @@ -19,16 +18,14 @@ use Fisharebest\Webtrees\Repository; </button> <div class="dropdown-menu dropdown-menu-right wt-page-menu-items" aria-labelledby="page-menu"> + <a class="dropdown-item" href="<?= route(EditRecordPage::class, ['xref' => $record->xref(), 'tree' => $record->tree()->name()]) ?>"> + <?= view('icons/edit') ?> + <?= I18N::translate('Edit') ?> + </a> + <a class="dropdown-item" href="#" data-confirm="<?= I18N::translate('Are you sure you want to delete “%s”?', strip_tags($record->fullName())) ?>" data-post-url="<?= e(route(DeleteRecord::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>"> <?= view('icons/delete') ?> <?= I18N::translate('Delete') ?> </a> - - <?php if (Auth::isAdmin() || $record->tree()->getPreference('SHOW_GEDCOM_RECORD')) : ?> - <a class="dropdown-item" href="<?= e(route(EditRawRecordPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>"> - <?= view('icons/edit') ?> - <?= I18N::translate('Edit the raw GEDCOM') ?> - </a> - <?php endif ?> </div> </div> diff --git a/resources/views/source-page-menu.phtml b/resources/views/source-page-menu.phtml index 60d58c9f2e..e6d32b41cf 100644 --- a/resources/views/source-page-menu.phtml +++ b/resources/views/source-page-menu.phtml @@ -1,8 +1,7 @@ <?php -use Fisharebest\Webtrees\Auth; use Fisharebest\Webtrees\Http\RequestHandlers\DeleteRecord; -use Fisharebest\Webtrees\Http\RequestHandlers\EditRawRecordPage; +use Fisharebest\Webtrees\Http\RequestHandlers\EditRecordPage; use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Source; @@ -19,17 +18,15 @@ use Fisharebest\Webtrees\Source; </button> <div class="dropdown-menu dropdown-menu-right wt-page-menu-items" aria-labelledby="page-menu"> + <a class="dropdown-item" href="<?= route(EditRecordPage::class, ['xref' => $record->xref(), 'tree' => $record->tree()->name()]) ?>"> + <?= view('icons/edit') ?> + <?= I18N::translate('Edit') ?> + </a> + <a class="dropdown-item" href="#" data-confirm="<?= I18N::translate('Are you sure you want to delete “%s”?', strip_tags($record->fullName())) ?>" data-post-url="<?= e(route(DeleteRecord::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>"> <?= view('icons/delete') ?> <?= I18N::translate('Delete') ?> </a> - - <?php if (Auth::isAdmin() || $record->tree()->getPreference('SHOW_GEDCOM_RECORD')) : ?> - <a class="dropdown-item" href="<?= e(route(EditRawRecordPage::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>"> - <?= view('icons/edit') ?> - <?= I18N::translate('Edit the raw GEDCOM') ?> - </a> - <?php endif ?> </div> </div> |
