Repository navigation
3.0.1
3.0.1 completes the 3.0 line. 3.0.0 was published from an early cut that carried only the place-format subsystem (PlaceProcessor, IsoCountryMap, the PlaceFormat* / PlaceStyle models — see the 3.0.0 notes); this release adds the two remaining API changes and the hardening/quality work that landed afterwards. Coming from 2.x, adopt this version rather than 3.0.0.
Breaking changes (since 3.0.0)
-
The legacy marriage-date methods were removed.
DateProcessor::getMarriageDate()andgetMarriageDateOfParents()are gone; no consumer called them. Marriage dates are served by the compact API only (getFormattedMarriageDate(),getFormattedMarriageDateOfParents(),getMarriageDateFull()). -
Model\NameAbbreviationis now a backed enum. The hand-rolledAUTO/GIVEN/SURNAMEstring constants, theCHOICESarray and the staticresolve(string, string): stringare replaced by enum cases (Auto/Given/Surname, backing values unchanged) with an instanceresolve(string $surnameTradition): self. A consumer validates a persisted preference withtryFrom()and resolves with$case->resolve(...). Stored preference values keep resolving, since the backing strings are unchanged.
Hardening and quality
-
VersionInformation's release-version check was hardened. It now rejects a non-http(s) update URL before the request, pins and bounds redirects (at most three hops, http(s) only), caps the response body it will buffer, validates the wholetag_nameagainst an anchored version pattern so nothing but a version reaches the admin upgrade notice, and bounds the request with a total timeout. Every operational failure degrades to the bundled version rather than breaking the control panel. (The URL is a first-party constant, so a host-level SSRF cannot manifest; that guard is deferred until the URL is ever made configurable.) -
IsoCountryMap's resolution cache is bounded. Only alpha-3-shaped tokens are memoised, so a whole-tree scan of ordinary place names no longer grows the cache to every distinct segment. -
The test suite exercises the published API. Reflection was removed throughout — every processor is constructed for real over stubbed collaborators and driven through its public methods, so the shipped contract three chart modules consume is what the tests pin. Coverage metadata is required on every test, the
tests/tree mirrorssrc/under an enforced gate, and every test class isfinal. -
Architecture and mutation gates.
phpatenforces the layer boundaries (no baseline, no exclusions); Infection gates the mutation score with a floor, measured with timeouts counted honestly. -
Documentation. The date accessors' plain-text-sink contract is documented on the public methods, and the README/AGENTS component inventory is current with the source tree.
Upgrading
Consumers pin ^2.x and are not moved by this release; adopt it when convenient. Where a PlaceProcessor is constructed directly, resolve the desired formatting into a spec first (unchanged from 3.0.0):
$spec = PlaceFormatChoice::CityCountry->toSpec($treeLevels, $treeSuffix);
$processor = new PlaceProcessor($individual, $spec, new IsoCountryMap());Replace any use of the removed NameAbbreviation constants/CHOICES/static resolve() with the enum cases (NameAbbreviation::tryFrom($stored) + $case->resolve($surnameTradition)), and any call to the removed getMarriageDate*() methods with the compact getFormattedMarriageDate*() / getMarriageDateFull() API.