-
-
Notifications
You must be signed in to change notification settings - Fork 43
Architecture
This page describes how the php-fhir code-generation pipeline works, from configuration to rendered PHP files.
┌───────────────────────────────┐
│ Config (+ VersionConfig[]) │ ← user-supplied settings
└──────────────┬────────────────┘
▼
┌───────────────────────────────┐
│ Builder │ orchestrates the whole process
└──────────────┬────────────────┘
│
┌──────────┴──────────┐
▼ ▼
Core Files Per-Version Pipeline
(shared) (repeated for each FHIR version)
│ │
│ ┌───────────┼──────────────┐
│ ▼ ▼ ▼
│ Definition Version Core Type Classes
│ (XSD parse) Files + Test Classes
│
└──► output/src output/tests
Namespace: DCarbone\PHPFHIR\Config
Holds all generation-time settings: output paths, namespace prefix, libxml options, and the list of
Version objects. Created by the user (or via Config::fromArray()), then handed to Builder.
Pure data object carrying per-version settings (name, schemaPath, namespace,
defaultConfig). Config wraps each one inside a full Version at construction time.
Namespace: DCarbone\PHPFHIR\Version
Represents a single FHIR version within a generation run. Provides:
-
getDefinition()— lazy-loadedDefinition(parses XSDs on first access). -
getVersionCoreFiles()/getVersionTestCoreFiles()—CoreFilesfor this version. -
getSourceMetadata()— FHIR copyright, generation date, and semantic version parsed fromfhir-base.xsd.
Parses a version's XSD schemas and builds a typed model of every FHIR type. The pipeline is:
-
TypeExtractor::parseTypes()— walks each.xsdand creates rawTypeinstances. -
TypeDecorator(multiple passes) — resolves parent types, restriction bases, component-of relationships, primitive flags, contained-type flags, comment containers, per-version overrides, and import lists. -
TypePropertyDecorator— resolves property types, names, and overloaded properties. -
TypeDecorationValidator— performs sanity checks on the fully-decorated type graph.
The result is a Types collection accessible via Definition::getTypes().
Parses the XML comment block at the top of fhir-base.xsd to extract:
- The FHIR copyright notice.
- The FHIR generation date.
- The FHIR semantic version string (e.g.
v4.0.1orv6.0.0-ballot4).
During parsing the version string is split on the first -:
-
_fhirVersionBase— the cleanvX.Y.Zportion, used for all Semver range comparisons. -
_fhirPreRelease— the suffix after-(e.g.ballot4), ornullfor GA releases.
This separation is necessary because Composer Semver rejects non-standard pre-release identifiers
such as ballot4; by stripping the suffix before calling Semver::satisfies() every range check
works correctly regardless of whether the source is a ballot build or a GA release.
Public API:
| Method | Returns | Description |
|---|---|---|
getSemanticVersion(bool) |
string |
Full version string, optionally with v prefix stripped. |
getShortVersion() |
string |
Major.Minor form of the base version (e.g. 6.0). |
getVersionInteger() |
int |
Integer derived from the base version; pre-release and GA share the same int. |
getPreRelease() |
null|string |
Pre-release identifier (e.g. ballot4), or null for GA. |
isPreRelease() |
bool |
true when a pre-release suffix is present. |
isDSTU1() … isR5()
|
bool |
Range checks against the base version. |
isR6() |
bool |
true for >= v6.0.0, < v7.0.0 (catches ballot builds as well as GA). |
Namespace: DCarbone\PHPFHIR\Builder
Orchestrates the entire render pipeline. Builder::render() calls, in order:
-
writeLibraryCoreEntities()— shared interfaces, traits, enums, the FHIR client, encoding helpers, and validation framework. -
writeLibraryTestClasses()— shared test mock classes and core tests. -
writeFHIRVersionCoreEntities()— per-versionVersion,VersionConstants,VersionTypeMap,VersionClient, enums, and interfaces. -
writeFHIRVersionTypeClasses()— one PHP class per FHIR type (primitives, elements, resources, resource containers, XHTML). -
writeFHIRVersionTestClasses()— per-version test core files. -
writeFHIRVersionTypeTestClasses()— one test class per non-abstract FHIR type.
A CoreFiles instance scans a template directory, pairs each template with an output path and
namespace, and wraps them in CoreFile objects. Each CoreFile knows:
- its template source path,
- its entity type (class, interface, trait, enum, test, exception),
- its output filepath,
- its fully-qualified namespace and class name,
- its
Imports(use-statements).
Static methods that require a template file and return the rendered PHP string. Templates are
plain PHP files that return a string; they receive contextual variables ($config, $version,
$type, $coreFile) via extract().
Templates live under the template/ directory:
template/
├── core/ ← shared core entities
│ ├── class_autoloader.php
│ ├── class_constants.php
│ ├── class_fhir_version.php
│ ├── client/ ← FHIR REST client
│ ├── encoding/ ← (Un)serialize config, XML writer, resource parser
│ ├── types/ ← Core interfaces & traits (TypeInterface, etc.)
│ ├── validation/ ← Validator, rules, traits
│ └── versions/ ← VersionConfig, VersionInterface, VersionTypeMapInterface
├── versions/
│ ├── core/ ← Per-version core (Version, VersionConstants, VersionTypeMap, …)
│ └── types/ ← Per-type class templates
│ ├── class_default.php
│ ├── class_primitive.php
│ ├── class_resource_container.php
│ ├── class_xhtml.php
│ ├── methods/ ← Getter/setter method fragments
│ ├── primitives/ ← Primitive-specific helpers
│ ├── properties/ ← Property declaration fragments
│ └── serialization/ ← JSON & XML (de)serialization fragments
└── tests/
├── core/ ← Shared test templates (mocks, etc.)
└── versions/
├── core/ ← Per-version test core templates
└── types/ ← Per-type test class template
Template filenames follow the convention <entity-type>_<name>.php:
| Prefix | Generated entity |
|---|---|
class_ |
Class |
interface_ |
Interface |
trait_ |
Trait |
enum_ |
Enum |
exception_ |
Exception class |
test_ |
PHPUnit test class |
These enums drive decisions during type decoration and rendering:
| Enum | Purpose |
|---|---|
TypeKindEnum |
Classifies each FHIR type (Primitive, Element, Resource, ResourceContainer, etc.) |
PrimitiveTypeEnum |
Maps FHIR primitive names to PHP scalar types |
PropertyUseEnum |
Indicates how a property is used (required, optional, prohibited) |
AttributeNameEnum |
Standard XSD attribute names encountered during parsing |
ElementNameEnum |
Standard XSD element names encountered during parsing |
Next: Generated Code →