Skip to content

Commit

Permalink
Using XMLParser for writing and XMLReader for Xhtml types
Browse files Browse the repository at this point in the history
  • Loading branch information
dcarbone authored May 2, 2024
1 parent f83de21 commit 3f1cfa8
Show file tree
Hide file tree
Showing 66 changed files with 869 additions and 889 deletions.
30 changes: 15 additions & 15 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@ jobs:
version: '${{ matrix.fhir-version }}'


load-fhir-validator:
runs-on: ubuntu-22.04
name: 'Download FHIR Validator'
steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/load-fhir-validator
# load-fhir-validator:
# runs-on: ubuntu-22.04
# name: 'Download FHIR Validator'
# steps:
# - uses: actions/checkout@v4
#
# - uses: ./.github/actions/load-fhir-validator

run:
runs-on: ubuntu-22.04
needs:
- load-fhir-source
- load-fhir-validator
# - load-fhir-validator
strategy:
fail-fast: false
matrix:
Expand All @@ -77,8 +77,8 @@ jobs:
with:
version: '${{ matrix.fhir-version }}'

- name: 'Install FHIR validator'
uses: ./.github/actions/load-fhir-validator
# - name: 'Install FHIR validator'
# uses: ./.github/actions/load-fhir-validator

- name: 'Install PHP'
uses: shivammathur/setup-php@v2
Expand Down Expand Up @@ -123,11 +123,11 @@ jobs:
run: |
./bin/generate.sh --useExisting --versions '${{ matrix.fhir-version }}'
- name: 'Install Java'
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 18
# - name: 'Install Java'
# uses: actions/setup-java@v4
# with:
# distribution: 'zulu'
# java-version: 18

- name: 'Run tests'
# language=sh
Expand Down
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ require 'path to PHPFHIRResponseParser.php';
// build config
$config = new \YourConfiguredNamespace\PHPFHIRResponseParserConfig([
'registerAutoloader' => true, // use if you are not using Composer
'libxmlOpts' => LIBXML_COMPACT | LIBXML_NSCLEAN // choose different libxml arguments if you want, ymmv.
'libxmlOpts' => LIBXML_NONET | LIBXML_BIGLINES | LIBXML_PARSEHUGE | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOXMLDECL // choose different libxml arguments if you want, ymmv.
'rootXmlns' => 'https://hl7.org/fhir', // a specific root xmlns to use, if the source does not return one
'overrideSourceXmlns' => true, // set this to true if you want the 'rootXmlns' value you defined to override any value seen from source
]);

// build parser
Expand All @@ -190,14 +192,19 @@ $json = json_encode($object);
## XML Serialization

```php
// To get an instance of \DOMElement...
$element = $object->xmlSerialize();
// To get an instance of \XMLWriter...
$xw = $object->xmlSerialize(null, $yourConfigInstance);

// to get as XML string...
$xml = $element->ownerDocument->saveXML($element);
$xml = $xw->outputMemory(true);

// you can alternatively have the output written directly to a file:
$xw = new \YourConfiguredNamespace\PHPFHIRXmlWriter();
$xw->openUri('file:///some/directory/fhir-resource.xml');
$object->xmlSerialize($xw, $yourConfigInstance);
```

XML Serialization utilizes [DOM](https://www.php.net/manual/en/book.dom.php).
XML Serialization utilizes [XMLWriter](https://www.php.net/manual/en/book.xmlwriter.php).

# Testing

Expand Down
3 changes: 2 additions & 1 deletion bin/generate.php
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@ function is_dir_empty(string $dir): bool

$url = $build_config->getUrl();

$namespace = $build_config->getNamespace(true);
// build vars
$namespace = $build_config->getFullyQualifiedName(true);
$version = trim($version);
$schema_dir = $config->getSchemaPath() . DIRECTORY_SEPARATOR . $version;

Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@
],
"require": {
"php": "^8.1",
"ext-simplexml": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-dom": "*",
"ext-simplexml": "*",
"psr/log": "^3.0"
},
"require-dev": {
"ext-curl": "*",
"ext-dom": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"phpunit/phpunit": "^10.5 || ^11.0",
"monolog/monolog": "^3.2.0"
},
Expand Down
6 changes: 2 additions & 4 deletions files/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,10 @@
const PHPFHIR_CLASSNAME_TYPEMAP = 'PHPFHIRTypeMap';
const PHPFHIR_CLASSNAME_DEBUG_CLIENT = 'PHPFHIRDebugClient';
const PHPFHIR_CLASSNAME_DEBUG_CLIENT_RESPONSE = 'PHPFHIRDebugClientResponse';
const PHPFHIR_CLASSNAME_XML_WRITER = 'PHPFHIRXmlWriter';

// Core interface names
const PHPFHIR_INTERFACE_TYPE = 'PHPFHIRTypeInterface';
const PHPFHIR_INTERFACE_XML_SERIALIZABLE = 'PHPFHIRXmlSerializableInterface';
const PHPFHIR_INTERFACE_XML_SERIALIZALE_CONFIG = 'PHPFHIRXmlSerializableConfigInterface';
const PHPFHIR_INTERFACE_CONTAINED_TYPE = 'PHPFHIRContainedTypeInterface';
const PHPFHIR_INTERFACE_COMMENT_CONTAINER = 'PHPFHIRCommentContainerInterface';
const PHPFHIR_INTERFACE_PRIMITIVE_TYPE = 'PHPFHIRPrimitiveTypeInterface';
Expand All @@ -98,8 +97,7 @@
const PHPFHIR_TRAIT_COMMENT_CONTAINER = 'PHPFHIRCommentContainerTrait';
const PHPFHIR_TRAIT_VALIDATION_ASSERTIONS = 'PHPFHIRValidationAssertionsTrait';
const PHPFHIR_TRAIT_CHANGE_TRACKING = 'PHPFHIRChangeTrackingTrait';
const PHPFHIR_TRAIT_XMLNS = 'PHPFHIRXmlNamespaceTrait';
const PHPFHIR_TRAIT_XML_SERIALIZABLE_CONFIG = 'PHPFHIRXmlSerializableConfigTrait';
const PHPFHIR_TRAIT_SOURCE_XMLNS = 'PHPFHIRSourceXmlNamespaceTrait';

// Core enums
const PHPFHIR_ENUM_CONFIG_KEY = 'PHPFHIRConfigKeyEnum';
Expand Down
4 changes: 2 additions & 2 deletions src/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,14 @@ protected function writeCoreTypeFiles(): void
$suffix = ucfirst($ftype);

// define "default" namespace
$ns = $this->config->getNamespace(true);
$ns = $this->config->getFullyQualifiedName(true);

if ('class' === $ftype) {
// 'class' types do have suffix
$suffix = '';
} else if ('test' === $ftype) {
// test classes have different namespace
$ns = $this->config->getTestsNamespace(TestType::BASE, true);
$ns = $this->config->getFullyQualifiedTestsName(TestType::BASE, true);
// trim subtype
$fname = substr($fname, strpos($fname, '_') + 1);
}
Expand Down
22 changes: 11 additions & 11 deletions src/Config/VersionConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,17 @@ public function getUrl(): string

/**
* @param bool $leadingSlash
* @param string ...$bits
* @return string
*/
public function getNamespace(bool $leadingSlash): string
public function getFullyQualifiedName(bool $leadingSlash, string... $bits): string
{
return $this->version->getNamespace($leadingSlash);
$ns = $this->version->getNamespace($leadingSlash);
$bits = array_filter($bits);
if ([] === $bits) {
return $ns;
}
return sprintf('%s\\%s', $ns, implode('\\' , $bits));
}

/**
Expand All @@ -104,18 +110,12 @@ public function getLibxmlOpts(): ?int
/**
* @param \DCarbone\PHPFHIR\Enum\TestType $testType
* @param bool $leadingSlash
* @param string ...$bits
* @return string
*/
public function getTestsNamespace(TestType $testType, bool $leadingSlash): string
public function getFullyQualifiedTestsName(TestType $testType, bool $leadingSlash, string... $bits): string
{
$ns = $this->getNamespace(false);

if ('' === $ns) {
$ns = $testType->namespaceSlug();
} else {
$ns .= '\\' . $testType->namespaceSlug();
}
return $leadingSlash ? "\\{$ns}" : $ns;
return $this->getFullyQualifiedName($leadingSlash, $testType->namespaceSlug(), ...$bits);
}

/**
Expand Down
3 changes: 0 additions & 3 deletions src/Definition.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ public function buildDefinition(): void
$log->info('Finding property types');
TypePropertyDecorator::findPropertyTypes($this->config, $this->types);

$log->info('Ensuring primitive type children have "value" property');
TypeDecorator::ensureValueOnPrimitiveChildTypes($this->config, $this->types);

$log->info('Finding overloaded properties in child types');
TypePropertyDecorator::findOverloadedProperties($this->config, $this->types);

Expand Down
46 changes: 6 additions & 40 deletions src/Definition/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,15 +273,7 @@ public function getClassName(): string
*/
public function getFullyQualifiedNamespace(bool $leadingSlash): string
{
$ns = $this->getConfig()->getNamespace(false);
$typeNS = $this->getTypeNamespace();
if ('' !== $typeNS) {
$ns = sprintf('%s\\%s', $ns, $typeNS);
}
return match ($leadingSlash) {
true => sprintf('\\%s', $ns),
false => $ns,
};
return $this->getConfig()->getFullyQualifiedName($leadingSlash, $this->getTypeNamespace());
}

/**
Expand All @@ -291,15 +283,7 @@ public function getFullyQualifiedNamespace(bool $leadingSlash): string
*/
public function getFullyQualifiedTestNamespace(TestType $testType, bool $leadingSlash): string
{
$ns = $this->getConfig()->getTestsNamespace($testType, false);
$typeNS = $this->getTypeNamespace();
if ('' !== $typeNS) {
$ns = sprintf('%s\\%s', $ns, $typeNS);
}
return match ($leadingSlash) {
true => sprintf('\\%s', $ns),
false => $ns,
};
return $this->getConfig()->getFullyQualifiedTestsName($testType, $leadingSlash,$this->getTypeNamespace());
}

/**
Expand All @@ -308,16 +292,7 @@ public function getFullyQualifiedTestNamespace(TestType $testType, bool $leading
*/
public function getFullyQualifiedClassName(bool $leadingSlash): string
{
$cn = $this->getFullyQualifiedNamespace(false);
if ('' === $cn) {
$cn = $this->getClassName();
} else {
$cn = sprintf('%s\\%s', $cn, $this->getClassName());
}
return match ($leadingSlash) {
true => sprintf('\\%s', $cn),
false => $cn,
};
return $this->getConfig()->getFullyQualifiedName($leadingSlash, $this->getTypeNamespace(), $this->getClassName());
}

/**
Expand All @@ -335,16 +310,7 @@ public function getTestClassName(): string
*/
public function getFullyQualifiedTestClassName($testType, bool $leadingSlash): string
{
$cn = $this->getFullyQualifiedTestNamespace($testType, false);
if ('' === $cn) {
$cn = $this->getTestClassName();
} else {
$cn = sprintf('%s\\%s', $cn, $this->getTestClassName());
}
return match ($leadingSlash) {
true => sprintf('\\%s', $cn),
false => $cn,
};
return $this->getConfig()->getFullyQualifiedTestsName($testType, $leadingSlash, $this->getTypeNamespace(), $this->getTestClassName());
}

/**
Expand Down Expand Up @@ -789,7 +755,7 @@ public function getDirectlyUsedTraits(): array
$traits,
PHPFHIR_TRAIT_VALIDATION_ASSERTIONS,
PHPFHIR_TRAIT_CHANGE_TRACKING,
PHPFHIR_TRAIT_XMLNS,
PHPFHIR_TRAIT_SOURCE_XMLNS,
);
}
} else if (!$parentType->hasLocalProperties()) {
Expand All @@ -799,7 +765,7 @@ public function getDirectlyUsedTraits(): array
$traits,
PHPFHIR_TRAIT_VALIDATION_ASSERTIONS,
PHPFHIR_TRAIT_CHANGE_TRACKING,
PHPFHIR_TRAIT_XMLNS,
PHPFHIR_TRAIT_SOURCE_XMLNS,
);
}

Expand Down
26 changes: 0 additions & 26 deletions src/Definition/TypeDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,32 +204,6 @@ public static function determinePrimitiveTypes(VersionConfig $config, Types $typ
}
}

/**
* @param \DCarbone\PHPFHIR\Config\VersionConfig $config
* @param \DCarbone\PHPFHIR\Definition\Types $types
*/
public static function ensureValueOnPrimitiveChildTypes(VersionConfig $config, Types $types): void
{
$logger = $config->getLogger();
foreach ($types->getIterator() as $type) {
if (!$type->hasPrimitiveParent() ||
null !== $type->getLocalProperties()->getProperty(PHPFHIR_VALUE_PROPERTY_NAME)) {
continue;
}
$logger->warning(
sprintf(
'Type "%s" extends primitive "%s" but is missing "%s" property. Adding...',
$type->getFHIRName(),
$type->getParentType()->getFHIRName(),
PHPFHIR_VALUE_PROPERTY_NAME
)
);
$property = new Property($type, $type->getSourceSXE(), $type->getSourceFilename());
$property->setName(PHPFHIR_VALUE_PROPERTY_NAME);
$type->getLocalProperties()->addProperty($property);
}
}

/**
* @param \DCarbone\PHPFHIR\Config\VersionConfig $config
* @param \DCarbone\PHPFHIR\Definition\Types $types
Expand Down
8 changes: 4 additions & 4 deletions src/Definition/TypeImports.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,15 @@ private function buildImports(): void
$this->addImport($this->type->getClassName(), $this->type->getFullyQualifiedNamespace(false));

$typeNS = $this->type->getFullyQualifiedNamespace(false);
$configNS = $this->type->getConfig()->getNamespace(false);
$configNS = $this->type->getConfig()->getFullyQualifiedName(false);

$sortedProperties = $this->type->getAllPropertiesIterator();

// always add xml serializable interface and root config to all non-abstract types
// non-abstract types must import config and xml writer
if (!$this->type->isAbstract()) {
$this->addImport(PHPFHIR_CLASSNAME_CONFIG, $configNS);
$this->addImport(PHPFHIR_INTERFACE_XML_SERIALIZABLE, $configNS);
$this->addImport(PHPFHIR_INTERFACE_XML_SERIALIZALE_CONFIG, $configNS);
$this->addImport(PHPFHIR_CLASSNAME_XML_WRITER, $configNS);
$this->addImport(PHPFHIR_ENUM_CONFIG_KEY, $configNS);
}

// if this type is in a nested namespace, there are a few base interfaces, classes, and traits
Expand Down
2 changes: 1 addition & 1 deletion src/Utilities/FileUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public static function buildAutoloaderRelativeFilepath(VersionConfig $config, Ty
{
return ltrim(
str_replace(
[$config->getNamespace(false), '\\'],
[$config->getFullyQualifiedName(false), '\\'],
['', '/'],
$type->getFullyQualifiedClassName(false)
),
Expand Down
2 changes: 1 addition & 1 deletion src/Utilities/TypeHintUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public static function typeTypeDoc(VersionConfig $config, Type $type, bool $null
if ($tk->isOneOf(TypeKind::RESOURCE_INLINE, TypeKind::RESOURCE_CONTAINER)) {
array_push(
$types,
sprintf('\\%s\\', trim($config->getNamespace(true), '\\')),
sprintf('\\%s\\', trim($config->getFullyQualifiedName(true), '\\')),
PHPFHIR_INTERFACE_CONTAINED_TYPE,
);
} else {
Expand Down
Loading

0 comments on commit 3f1cfa8

Please sign in to comment.