diff options
Diffstat (limited to 'vendor/sabre/xml/lib/Deserializer')
-rw-r--r-- | vendor/sabre/xml/lib/Deserializer/functions.php | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/vendor/sabre/xml/lib/Deserializer/functions.php b/vendor/sabre/xml/lib/Deserializer/functions.php index 0eff4b7e0..c4f240970 100644 --- a/vendor/sabre/xml/lib/Deserializer/functions.php +++ b/vendor/sabre/xml/lib/Deserializer/functions.php @@ -173,7 +173,7 @@ function enum(Reader $reader, string $namespace = null): array if (!is_null($namespace) && $namespace === $reader->namespaceURI) { $values[] = $reader->localName; } else { - $values[] = $reader->getClark(); + $values[] = (string) $reader->getClark(); } } while ($reader->depth >= $currentDepth && $reader->next()); @@ -316,3 +316,44 @@ function mixedContent(Reader $reader): array return $content; } + +/** + * The functionCaller deserializer turns an xml element into whatever your callable return. + * + * You can use, e.g., a named constructor (factory method) to create an object using + * this function. + * + * @return mixed + */ +function functionCaller(Reader $reader, callable $func, string $namespace) +{ + if ($reader->isEmptyElement) { + $reader->next(); + + return null; + } + + $funcArgs = []; + $func = is_string($func) && false !== strpos($func, '::') ? explode('::', $func) : $func; + $ref = is_array($func) ? new \ReflectionMethod($func[0], $func[1]) : new \ReflectionFunction($func); + foreach ($ref->getParameters() as $parameter) { + $funcArgs[$parameter->getName()] = null; + } + + $reader->read(); + do { + if (Reader::ELEMENT === $reader->nodeType && $reader->namespaceURI == $namespace) { + if (array_key_exists($reader->localName, $funcArgs)) { + $funcArgs[$reader->localName] = $reader->parseCurrentElement()['value']; + } else { + // Ignore property + $reader->next(); + } + } else { + $reader->read(); + } + } while (Reader::END_ELEMENT !== $reader->nodeType); + $reader->read(); + + return $func(...array_values($funcArgs)); +} |