@@ -31,6 +31,18 @@ class SourceMetadata
3131 private string $ _fhirGenerationDate ;
3232 private string $ _fhirVersion ;
3333
34+ /**
35+ * The base version string with any pre-release suffix stripped.
36+ * e.g. 'v6.0.0-ballot4' -> 'v6.0.0'.
37+ * Used for all Semver range comparisons.
38+ */
39+ private string $ _fhirVersionBase ;
40+
41+ /**
42+ * The pre-release identifier, if any (e.g. 'ballot4'). Null for GA releases.
43+ */
44+ private null |string $ _fhirPreRelease = null ;
45+
3446 public function __construct (string $ schemPath )
3547 {
3648 $ this ->_schemaPath = $ schemPath ;
@@ -65,14 +77,14 @@ public function getSemanticVersion(bool $trimmed): string
6577 }
6678
6779 /**
68- * Return the shortenend representation of the FHIR semantic version containing only Manjor .Minor values.
80+ * Return the shortenend representation of the FHIR semantic version containing only Major .Minor values.
6981 *
7082 * @return string
7183 */
7284 public function getShortVersion (): string
7385 {
7486 $ this ->_compile ();
75- $ v = ltrim ($ this ->_fhirVersion );
87+ $ v = ltrim ($ this ->_fhirVersionBase , ' v ' );
7688 return match (substr_count ($ v , '. ' )) {
7789 1 => $ v ,
7890 2 => substr ($ v , 0 , strrpos ($ v , '. ' )),
@@ -82,13 +94,43 @@ public function getShortVersion(): string
8294
8395 /**
8496 * Returns an integer representation of the FHIR semantic version.
97+ * Pre-release suffixes are ignored; the integer is derived from the base
98+ * version only, so 'v6.0.0-ballot4' and 'v6.0.0' produce the same value.
99+ * Use isPreRelease() to distinguish ballot from GA releases.
85100 *
86101 * @return int
87102 */
88103 public function getVersionInteger (): int
89104 {
90105 $ this ->_compile ();
91- return intval (sprintf ("%'.-08s " , str_replace (['v ' , '. ' ], '' , $ this ->_fhirVersion )));
106+ return intval (sprintf ("%'.-08s " , str_replace (['v ' , '. ' ], '' , $ this ->_fhirVersionBase )));
107+ }
108+
109+ /**
110+ * Returns the pre-release identifier extracted from the FHIR version string,
111+ * or null if this is a GA release.
112+ *
113+ * e.g. 'v6.0.0-ballot4' -> 'ballot4'
114+ * 'v5.0.0' -> null
115+ *
116+ * @return string|null
117+ */
118+ public function getPreRelease (): null |string
119+ {
120+ $ this ->_compile ();
121+ return $ this ->_fhirPreRelease ;
122+ }
123+
124+ /**
125+ * Returns true when the FHIR source version carries a pre-release suffix
126+ * (e.g. '-ballot4').
127+ *
128+ * @return bool
129+ */
130+ public function isPreRelease (): bool
131+ {
132+ $ this ->_compile ();
133+ return null !== $ this ->_fhirPreRelease ;
92134 }
93135
94136 /**
@@ -98,42 +140,59 @@ public function getVersionInteger(): int
98140 */
99141 public function isDSTU1 (): bool
100142 {
101- return Semver::satisfies ($ this ->getSemanticVersion ( false ), '< v1.0.0 ' );
143+ return Semver::satisfies ($ this ->_getVersionBase ( ), '< v1.0.0 ' );
102144 }
103145
104146 public function isDSTU2 (): bool
105147 {
106- $ semver = $ this ->getSemanticVersion ( false );
107- return Semver::satisfies ($ semver , '>= v1.0.0 ' )
108- && Semver::satisfies ($ semver , '< v3.0.0 ' );
148+ $ base = $ this ->_getVersionBase ( );
149+ return Semver::satisfies ($ base , '>= v1.0.0 ' )
150+ && Semver::satisfies ($ base , '< v3.0.0 ' );
109151 }
110152
111153 public function isSTU3 (): bool
112154 {
113- $ semver = $ this ->getSemanticVersion ( false );
114- return Semver::satisfies ($ semver , '>= v3.0.0 ' )
115- && Semver::satisfies ($ semver , '< v4.0.0 ' );
155+ $ base = $ this ->_getVersionBase ( );
156+ return Semver::satisfies ($ base , '>= v3.0.0 ' )
157+ && Semver::satisfies ($ base , '< v4.0.0 ' );
116158 }
117159
118160 public function isR4 (): bool
119161 {
120- $ semver = $ this ->getSemanticVersion ( false );
121- return Semver::satisfies ($ semver , '>= v4.0.0 ' )
122- && Semver::satisfies ($ semver , '< v4.3.0 ' );
162+ $ base = $ this ->_getVersionBase ( );
163+ return Semver::satisfies ($ base , '>= v4.0.0 ' )
164+ && Semver::satisfies ($ base , '< v4.3.0 ' );
123165 }
124166
125167 public function isR4B (): bool
126168 {
127- $ semver = $ this ->getSemanticVersion ( false );
128- return Semver::satisfies ($ semver , '>= v4.3.0 ' )
129- && Semver::satisfies ($ semver , '< v5.0.0 ' );
169+ $ base = $ this ->_getVersionBase ( );
170+ return Semver::satisfies ($ base , '>= v4.3.0 ' )
171+ && Semver::satisfies ($ base , '< v5.0.0 ' );
130172 }
131173
132174 public function isR5 (): bool
133175 {
134- $ semver = $ this ->getSemanticVersion (false );
135- return Semver::satisfies ($ semver , '>= v5.0.0 ' )
136- && Semver::satisfies ($ semver , '< v6.0.0 ' );
176+ $ base = $ this ->_getVersionBase ();
177+ return Semver::satisfies ($ base , '>= v5.0.0 ' )
178+ && Semver::satisfies ($ base , '< v6.0.0 ' );
179+ }
180+
181+ public function isR6 (): bool
182+ {
183+ $ base = $ this ->_getVersionBase ();
184+ return Semver::satisfies ($ base , '>= v6.0.0 ' )
185+ && Semver::satisfies ($ base , '< v7.0.0 ' );
186+ }
187+
188+ /**
189+ * Returns the compiled base version (without pre-release suffix) for use
190+ * in Semver range comparisons.
191+ */
192+ private function _getVersionBase (): string
193+ {
194+ $ this ->_compile ();
195+ return $ this ->_fhirVersionBase ;
137196 }
138197
139198 private function _compile (): void
@@ -180,6 +239,15 @@ private function _compile(): void
180239 $ version = trim ($ version );
181240 if (str_starts_with ($ version , 'v ' )) {
182241 $ this ->_fhirVersion = $ version ;
242+ // Split off any pre-release suffix (e.g. 'v6.0.0-ballot4').
243+ $ dashPos = strpos ($ version , '- ' );
244+ if (false !== $ dashPos ) {
245+ $ this ->_fhirVersionBase = substr ($ version , 0 , $ dashPos );
246+ $ this ->_fhirPreRelease = substr ($ version , $ dashPos + 1 );
247+ } else {
248+ $ this ->_fhirVersionBase = $ version ;
249+ $ this ->_fhirPreRelease = null ;
250+ }
183251 } else {
184252 throw new \LogicException (
185253 sprintf (
0 commit comments