Passed
Push — develop ( df1f3f...87a4e2 )
by Greg
11:15
created

ElementFactory::gedcom551()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 473
Code Lines 471

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 471
nc 1
nop 0
dl 0
loc 473
rs 8
c 0
b 0
f 0

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2022 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Factories;
21
22
use Fisharebest\Webtrees\Contracts\ElementFactoryInterface;
23
use Fisharebest\Webtrees\Contracts\ElementInterface;
24
use Fisharebest\Webtrees\Elements\AddressCity;
25
use Fisharebest\Webtrees\Elements\AddressCountry;
26
use Fisharebest\Webtrees\Elements\AddressEmail;
27
use Fisharebest\Webtrees\Elements\AddressFax;
28
use Fisharebest\Webtrees\Elements\AddressLine;
29
use Fisharebest\Webtrees\Elements\AddressLine1;
30
use Fisharebest\Webtrees\Elements\AddressLine2;
31
use Fisharebest\Webtrees\Elements\AddressLine3;
32
use Fisharebest\Webtrees\Elements\AddressPostalCode;
33
use Fisharebest\Webtrees\Elements\AddressState;
34
use Fisharebest\Webtrees\Elements\AddressWebPage;
35
use Fisharebest\Webtrees\Elements\AdoptedByWhichParent;
36
use Fisharebest\Webtrees\Elements\Adoption;
37
use Fisharebest\Webtrees\Elements\AdultChristening;
38
use Fisharebest\Webtrees\Elements\AgeAtEvent;
39
use Fisharebest\Webtrees\Elements\AncestralFileNumber;
40
use Fisharebest\Webtrees\Elements\Annulment;
41
use Fisharebest\Webtrees\Elements\ApprovedSystemId;
42
use Fisharebest\Webtrees\Elements\AutomatedRecordId;
43
use Fisharebest\Webtrees\Elements\Baptism;
44
use Fisharebest\Webtrees\Elements\BarMitzvah;
45
use Fisharebest\Webtrees\Elements\BasMitzvah;
46
use Fisharebest\Webtrees\Elements\Birth;
47
use Fisharebest\Webtrees\Elements\Blessing;
48
use Fisharebest\Webtrees\Elements\Burial;
49
use Fisharebest\Webtrees\Elements\CasteName;
50
use Fisharebest\Webtrees\Elements\CauseOfEvent;
51
use Fisharebest\Webtrees\Elements\Census;
52
use Fisharebest\Webtrees\Elements\CertaintyAssessment;
53
use Fisharebest\Webtrees\Elements\Change;
54
use Fisharebest\Webtrees\Elements\ChangeDate;
55
use Fisharebest\Webtrees\Elements\CharacterSet;
56
use Fisharebest\Webtrees\Elements\ChildLinkageStatus;
57
use Fisharebest\Webtrees\Elements\Christening;
58
use Fisharebest\Webtrees\Elements\Confirmation;
59
use Fisharebest\Webtrees\Elements\ContentDescription;
60
use Fisharebest\Webtrees\Elements\Coordinates;
61
use Fisharebest\Webtrees\Elements\CopyrightFile;
62
use Fisharebest\Webtrees\Elements\CopyrightSourceData;
63
use Fisharebest\Webtrees\Elements\CountOfChildren;
64
use Fisharebest\Webtrees\Elements\CountOfMarriages;
65
use Fisharebest\Webtrees\Elements\Cremation;
66
use Fisharebest\Webtrees\Elements\CustomElement;
67
use Fisharebest\Webtrees\Elements\CustomEvent;
68
use Fisharebest\Webtrees\Elements\CustomFact;
69
use Fisharebest\Webtrees\Elements\CustomFamilyEvent;
70
use Fisharebest\Webtrees\Elements\CustomIndividualEvent;
71
use Fisharebest\Webtrees\Elements\DateLdsOrd;
72
use Fisharebest\Webtrees\Elements\DateValue;
73
use Fisharebest\Webtrees\Elements\Death;
74
use Fisharebest\Webtrees\Elements\DescriptiveTitle;
75
use Fisharebest\Webtrees\Elements\Divorce;
76
use Fisharebest\Webtrees\Elements\DivorceFiled;
77
use Fisharebest\Webtrees\Elements\Emigration;
78
use Fisharebest\Webtrees\Elements\EmptyElement;
79
use Fisharebest\Webtrees\Elements\Engagement;
80
use Fisharebest\Webtrees\Elements\EntryRecordingDate;
81
use Fisharebest\Webtrees\Elements\EventAttributeType;
82
use Fisharebest\Webtrees\Elements\EventOrFactClassification;
83
use Fisharebest\Webtrees\Elements\EventsRecorded;
84
use Fisharebest\Webtrees\Elements\EventTypeCitedFrom;
85
use Fisharebest\Webtrees\Elements\FamilyCensus;
86
use Fisharebest\Webtrees\Elements\FamilyRecord;
87
use Fisharebest\Webtrees\Elements\FamilyResidence;
88
use Fisharebest\Webtrees\Elements\FamilySearchFamilyTreeId;
89
use Fisharebest\Webtrees\Elements\FamilyStatusText;
90
use Fisharebest\Webtrees\Elements\FileName;
91
use Fisharebest\Webtrees\Elements\FirstCommunion;
92
use Fisharebest\Webtrees\Elements\Form;
93
use Fisharebest\Webtrees\Elements\GedcomElement;
94
use Fisharebest\Webtrees\Elements\GenerationsOfAncestors;
95
use Fisharebest\Webtrees\Elements\GenerationsOfDescendants;
96
use Fisharebest\Webtrees\Elements\GovIdentifier;
97
use Fisharebest\Webtrees\Elements\Graduation;
98
use Fisharebest\Webtrees\Elements\HeaderRecord;
99
use Fisharebest\Webtrees\Elements\HierarchicalRelationship;
100
use Fisharebest\Webtrees\Elements\Immigration;
101
use Fisharebest\Webtrees\Elements\IndividualRecord;
102
use Fisharebest\Webtrees\Elements\LanguageId;
103
use Fisharebest\Webtrees\Elements\LdsBaptism;
104
use Fisharebest\Webtrees\Elements\LdsBaptismDateStatus;
105
use Fisharebest\Webtrees\Elements\LdsChildSealing;
106
use Fisharebest\Webtrees\Elements\LdsChildSealingDateStatus;
107
use Fisharebest\Webtrees\Elements\LdsConfirmation;
108
use Fisharebest\Webtrees\Elements\LdsEndowment;
109
use Fisharebest\Webtrees\Elements\LdsEndowmentDateStatus;
110
use Fisharebest\Webtrees\Elements\LdsSpouseSealing;
111
use Fisharebest\Webtrees\Elements\LdsSpouseSealingDateStatus;
112
use Fisharebest\Webtrees\Elements\LocationRecord;
113
use Fisharebest\Webtrees\Elements\MaidenheadLocator;
114
use Fisharebest\Webtrees\Elements\Marriage;
115
use Fisharebest\Webtrees\Elements\MarriageBanns;
116
use Fisharebest\Webtrees\Elements\MarriageContract;
117
use Fisharebest\Webtrees\Elements\MarriageLicence;
118
use Fisharebest\Webtrees\Elements\MarriageSettlement;
119
use Fisharebest\Webtrees\Elements\MarriageType;
120
use Fisharebest\Webtrees\Elements\MediaRecord;
121
use Fisharebest\Webtrees\Elements\MultimediaFileReference;
122
use Fisharebest\Webtrees\Elements\MultimediaFormat;
123
use Fisharebest\Webtrees\Elements\NameOfBusiness;
124
use Fisharebest\Webtrees\Elements\NameOfFamilyFile;
125
use Fisharebest\Webtrees\Elements\NameOfProduct;
126
use Fisharebest\Webtrees\Elements\NameOfRepository;
127
use Fisharebest\Webtrees\Elements\NameOfSourceData;
128
use Fisharebest\Webtrees\Elements\NamePersonal;
129
use Fisharebest\Webtrees\Elements\NamePhoneticVariation;
130
use Fisharebest\Webtrees\Elements\NamePieceGiven;
131
use Fisharebest\Webtrees\Elements\NamePieceNickname;
132
use Fisharebest\Webtrees\Elements\NamePiecePrefix;
133
use Fisharebest\Webtrees\Elements\NamePieceSuffix;
134
use Fisharebest\Webtrees\Elements\NamePieceSurname;
135
use Fisharebest\Webtrees\Elements\NamePieceSurnamePrefix;
136
use Fisharebest\Webtrees\Elements\NameRomanizedVariation;
137
use Fisharebest\Webtrees\Elements\NameType;
138
use Fisharebest\Webtrees\Elements\NationalIdNumber;
139
use Fisharebest\Webtrees\Elements\NationOrTribalOrigin;
140
use Fisharebest\Webtrees\Elements\Naturalization;
141
use Fisharebest\Webtrees\Elements\NobilityTypeTitle;
142
use Fisharebest\Webtrees\Elements\NoteRecord;
143
use Fisharebest\Webtrees\Elements\NoteStructure;
144
use Fisharebest\Webtrees\Elements\Occupation;
145
use Fisharebest\Webtrees\Elements\OrdinanceProcessFlag;
146
use Fisharebest\Webtrees\Elements\Ordination;
147
use Fisharebest\Webtrees\Elements\PafUid;
148
use Fisharebest\Webtrees\Elements\PedigreeLinkageType;
149
use Fisharebest\Webtrees\Elements\PermanentRecordFileNumber;
150
use Fisharebest\Webtrees\Elements\PhoneNumber;
151
use Fisharebest\Webtrees\Elements\PhoneticType;
152
use Fisharebest\Webtrees\Elements\PhysicalDescription;
153
use Fisharebest\Webtrees\Elements\PlaceHierarchy;
154
use Fisharebest\Webtrees\Elements\PlaceLatitude;
155
use Fisharebest\Webtrees\Elements\PlaceLivingOrdinance;
156
use Fisharebest\Webtrees\Elements\PlaceLongtitude;
157
use Fisharebest\Webtrees\Elements\PlaceName;
158
use Fisharebest\Webtrees\Elements\PlacePhoneticVariation;
159
use Fisharebest\Webtrees\Elements\PlaceRomanizedVariation;
160
use Fisharebest\Webtrees\Elements\Possessions;
161
use Fisharebest\Webtrees\Elements\Probate;
162
use Fisharebest\Webtrees\Elements\PublicationDate;
163
use Fisharebest\Webtrees\Elements\ReceivingSystemName;
164
use Fisharebest\Webtrees\Elements\RelationIsDescriptor;
165
use Fisharebest\Webtrees\Elements\ReligiousAffiliation;
166
use Fisharebest\Webtrees\Elements\RepositoryRecord;
167
use Fisharebest\Webtrees\Elements\ResearchTask;
168
use Fisharebest\Webtrees\Elements\ResearchTaskPriority;
169
use Fisharebest\Webtrees\Elements\ResearchTaskStatus;
170
use Fisharebest\Webtrees\Elements\ResearchTaskType;
171
use Fisharebest\Webtrees\Elements\Residence;
172
use Fisharebest\Webtrees\Elements\ResponsibleAgency;
173
use Fisharebest\Webtrees\Elements\RestrictionNotice;
174
use Fisharebest\Webtrees\Elements\Retirement;
175
use Fisharebest\Webtrees\Elements\RoleInEvent;
176
use Fisharebest\Webtrees\Elements\RomanizedType;
177
use Fisharebest\Webtrees\Elements\ScholasticAchievement;
178
use Fisharebest\Webtrees\Elements\SexValue;
179
use Fisharebest\Webtrees\Elements\SexXValue;
180
use Fisharebest\Webtrees\Elements\SocialSecurityNumber;
181
use Fisharebest\Webtrees\Elements\SourceCallNumber;
182
use Fisharebest\Webtrees\Elements\SourceData;
183
use Fisharebest\Webtrees\Elements\SourceFiledByEntry;
184
use Fisharebest\Webtrees\Elements\SourceJurisdictionPlace;
185
use Fisharebest\Webtrees\Elements\SourceMediaType;
186
use Fisharebest\Webtrees\Elements\SourceOriginator;
187
use Fisharebest\Webtrees\Elements\SourcePublicationFacts;
188
use Fisharebest\Webtrees\Elements\SourceRecord;
189
use Fisharebest\Webtrees\Elements\SubmissionRecord;
190
use Fisharebest\Webtrees\Elements\SubmitterName;
191
use Fisharebest\Webtrees\Elements\SubmitterRecord;
192
use Fisharebest\Webtrees\Elements\SubmitterRegisteredRfn;
193
use Fisharebest\Webtrees\Elements\SubmitterText;
194
use Fisharebest\Webtrees\Elements\TempleCode;
195
use Fisharebest\Webtrees\Elements\TextFromSource;
196
use Fisharebest\Webtrees\Elements\TimeValue;
197
use Fisharebest\Webtrees\Elements\TransmissionDate;
198
use Fisharebest\Webtrees\Elements\UnknownElement;
199
use Fisharebest\Webtrees\Elements\UserReferenceNumber;
200
use Fisharebest\Webtrees\Elements\UserReferenceType;
201
use Fisharebest\Webtrees\Elements\VersionNumber;
202
use Fisharebest\Webtrees\Elements\WebtreesUser;
203
use Fisharebest\Webtrees\Elements\WhereWithinSource;
204
use Fisharebest\Webtrees\Elements\Will;
205
use Fisharebest\Webtrees\Elements\XrefAssociate;
206
use Fisharebest\Webtrees\Elements\XrefFamily;
207
use Fisharebest\Webtrees\Elements\XrefIndividual;
208
use Fisharebest\Webtrees\Elements\XrefLocation;
209
use Fisharebest\Webtrees\Elements\XrefMedia;
210
use Fisharebest\Webtrees\Elements\XrefRepository;
211
use Fisharebest\Webtrees\Elements\XrefSource;
212
use Fisharebest\Webtrees\Elements\XrefSubmission;
213
use Fisharebest\Webtrees\Elements\XrefSubmitter;
214
use Fisharebest\Webtrees\I18N;
215
216
use function array_merge;
217
use function preg_match;
218
use function var_dump;
219
220
/**
221
 * Make a GEDCOM element.
222
 */
223
class ElementFactory implements ElementFactoryInterface
224
{
225
    /** @var array<string,ElementInterface> */
226
    private array $elements = [];
227
228
    /**
229
     * Create a GEDCOM element that corresponds to a GEDCOM tag.
230
     * Finds the correct element for all valid tags.
231
     * Finds a likely element for custom tags.
232
     *
233
     * @param string $tag - Colon delimited hierarchy, e.g. 'INDI:BIRT:PLAC'
234
     *
235
     * @return ElementInterface
236
     */
237
    public function make(string $tag): ElementInterface
238
    {
239
        return $this->elements[$tag] ?? $this->findElementByWildcard($tag) ?? new UnknownElement($tag);
240
    }
241
242
    /**
243
     * Register GEDCOM tags.
244
     *
245
     * @param array<string,ElementInterface> $elements
246
     */
247
    public function registerTags(array $elements): void
248
    {
249
        $this->elements = $elements + $this->elements;
250
    }
251
252
    /**
253
     * Register more subtags.
254
     *
255
     * @param array<string,array<int,array<int,string>>> $subtags
256
     */
257
    public function registerSubTags(array $subtags): void
258
    {
259
        foreach ($subtags as $tag => $children) {
260
            foreach ($children as $child) {
261
                $this->make($tag)->subtag(...$child);
262
            }
263
        }
264
    }
265
266
    /**
267
     * @param string $tag
268
     *
269
     * @return ElementInterface|null
270
     */
271
    private function findElementByWildcard(string $tag): ?ElementInterface
272
    {
273
        foreach ($this->elements as $tags => $element) {
274
            if (str_contains($tags, '*')) {
275
                $regex = '/^' . strtr($tags, ['*' => '[^:]+']) . '$/';
276
277
                if (preg_match($regex, $tag)) {
278
                    return $element;
279
                }
280
            }
281
        }
282
283
        return null;
284
    }
285
}
286