3 namespace OpenEMR\FHIR\R4
;
6 * This class was generated with the PHPFHIR library (https://github.com/dcarbone/php-fhir) using
7 * class definitions from HL7 FHIR (https://www.hl7.org/fhir/)
9 * Class creation date: June 14th, 2019
13 * Copyright 2016-2017 Daniel Carbone (daniel.p.carbone@gmail.com)
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
19 * http://www.apache.org/licenses/LICENSE-2.0
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
29 class PHPFHIRResponseParser
32 * If response is XML, these arguments will be passed into the \SimpleXMLElement constructor
33 * @see http://php.net/manual/en/libxml.constants.php for a list of options.
36 public static $sxeArgs = null;
38 /** @var PHPFHIRParserMap */
44 * @param bool $registerAutoloader
46 public function __construct($registerAutoloader = true)
48 if (null === self
::$sxeArgs) {
49 self
::$sxeArgs = LIBXML_COMPACT | LIBXML_NSCLEAN
;
52 if ($registerAutoloader) {
53 self
::_registerAutoloader();
56 $this->_parserMap
= new PHPFHIRParserMap();
60 * @param string $input
61 * @return object Root object type depends on initial query type and parameters
63 public function parse($input)
65 if (!is_string($input)) {
66 throw $this->_createNonStringArgumentException($input);
69 switch (substr($input, 0, 1)) {
71 return $this->_parseXML($input);
74 return $this->_parseJson($input);
77 throw new \
RuntimeException(sprintf(
78 '%s::parse - Unable to determine response type, expected JSON or XML.',
85 * @param string $input
88 private function _parseJson($input)
90 $decoded = json_decode($input, true);
92 $lastError = json_last_error();
93 if (JSON_ERROR_NONE
=== $lastError) {
94 return $this->_parseJsonObject($decoded, $decoded['resourceType']);
97 throw new \
DomainException(sprintf(
98 '%s::parse - Error encountered while decoding json input. Error code: %s',
105 * @param string $input
108 private function _parseXML($input)
110 libxml_use_internal_errors(true);
111 $sxe = new \
SimpleXMLElement($input, self
::$sxeArgs);
112 $error = libxml_get_last_error();
113 libxml_use_internal_errors(false);
115 if ($sxe instanceof \SimpleXMLElement
) {
116 return $this->_parseXMLNode($sxe, $sxe->getName());
119 throw new \
RuntimeException(sprintf(
120 'Unable to parse response: "%s"',
121 ($error ?
$error->message
: 'Unknown Error')
126 * @param array $jsonEntry
127 * @param string $fhirElementName
130 private function _parseJsonObject($jsonEntry, $fhirElementName)
132 if ('html' === $fhirElementName) {
136 if (false !== strpos($fhirElementName, '-primitive') ||
false !== strpos($fhirElementName, '-list')) {
140 $map = $this->_tryGetMapEntry($fhirElementName);
142 $fullClassName = $map['fullClassName'];
143 $properties = $map['properties'];
145 $object = new $fullClassName();
147 // This indicates we are at a primitive value...
148 if (is_scalar($jsonEntry)) {
149 if (isset($properties['value'])) {
150 $propertyMap = $properties['value'];
151 $setter = $propertyMap['setter'];
152 $element = $propertyMap['element'];
154 if (sprintf('%s-primitive', $fhirElementName) === $element ||
sprintf('%s-list', $fhirElementName) === $element) {
155 $object->$setter($jsonEntry);
157 $this->_triggerPropertyNotFoundError($fhirElementName, 'value');
160 $this->_triggerPropertyNotFoundError($fhirElementName, 'value');
162 } elseif (isset($jsonEntry['resourceType']) && $jsonEntry['resourceType'] !== $fhirElementName) { // TODO:
163 // This is probably very not ok...
164 $propertyMap = $properties[$jsonEntry['resourceType']];
165 $setter = $propertyMap['setter'];
166 $element = $propertyMap['element'];
167 $object->$setter($this->_parseJsonObject($jsonEntry, $element));
169 foreach ($jsonEntry as $k => $v) {
172 case 'fhir_comments':
176 if (!isset($properties[$k])) {
177 $this->_triggerPropertyNotFoundError($fhirElementName, $k);
181 $propertyMap = $properties[$k];
182 $setter = $propertyMap['setter'];
183 $element = $propertyMap['element'];
188 if (is_string($firstKey)) {
189 $object->$setter($this->_parseJsonObject($v, $element));
191 foreach ($v as $child) {
192 $object->$setter($this->_parseJsonObject($child, $element));
196 $object->$setter($this->_parseJsonObject($v, $element));
205 * @param \SimpleXMLElement $element
206 * @param string $fhirElementName
209 private function _parseXMLNode(\SimpleXMLElement
$element, $fhirElementName)
211 if ('html' === $fhirElementName) {
212 return $element->saveXML();
215 if (false !== strpos($fhirElementName, '-primitive') ||
false !== strpos($fhirElementName, '-list')) {
216 return (string)$element;
219 $map = $this->_tryGetMapEntry($fhirElementName);
221 $fullClassName = $map['fullClassName'];
222 $properties = $map['properties'];
224 $object = new $fullClassName();
226 /** @var \SimpleXMLElement $attribute */
227 foreach ($element->attributes() as $attribute) {
228 $childName = $attribute->getName();
229 if (!isset($properties[$childName])) {
230 $this->_triggerPropertyNotFoundError($fhirElementName, $childName);
234 $propertyMap = $properties[$childName];
235 $setter = $propertyMap['setter'];
237 $object->$setter((string)$attribute);
240 /** @var \SimpleXMLElement $childElement */
241 foreach ($element->children() as $childElement) {
242 $childName = $childElement->getName();
243 if (!isset($properties[$childName])) {
244 $this->_triggerPropertyNotFoundError($fhirElementName, $childName);
248 $propertyMap = $properties[$childName];
249 $setter = $propertyMap['setter'];
250 $element = $propertyMap['element'];
252 $object->$setter($this->_parseXMLNode($childElement, $element));
259 * @param string $fhirElementName
262 private function _tryGetMapEntry($fhirElementName)
264 if (!isset($this->_parserMap
[$fhirElementName])) {
265 throw new \
RuntimeException(sprintf(
266 'Element map does not contain entry for "%s". This indicates either malformed response or bug in class generation.',
271 return $this->_parserMap
[$fhirElementName];
275 * @param string $fhirElementName
276 * @param string $propertyName
279 private function _triggerPropertyNotFoundError($fhirElementName, $propertyName)
281 return trigger_error(sprintf(
282 'Could not find mapped property called "%s" on object "%s". This could indicate malformed response or bug in class generator.',
289 * @param mixed $input
290 * @return \InvalidArgumentException
292 private function _createNonStringArgumentException($input)
294 return new \
InvalidArgumentException(sprintf(
295 '%s::parse - Argument 1 expected to be string, %s seen.',
301 private static function _registerAutoloader()
303 $autoloaderClass = __NAMESPACE__
. '\PHPFHIRAutoloader';
304 $autoloaderClassFile = __DIR__
. '/PHPFHIRAutoloader.php';
306 if (!class_exists($autoloaderClass, false)) {
307 if (!file_exists($autoloaderClassFile)) {
308 throw new \
RuntimeException(sprintf(
309 'PHPFHIRAutoloader class is not defined and was not found at expected location "%s".',
314 require $autoloaderClassFile;
317 $autoloaderClass::register();