} */ class PropfindRequestAnalyzer { private const KNOWN_PROPS = [ 'resourceType', 'contentType', 'lastModified', 'creationDate', 'contentLength', 'etag', 'supportedLock', ]; /** * @return davProperties */ public function getRequestedProperties(\DOMDocument $request): array { $propfinds = $request->getElementsByTagNameNS('DAV:', 'propfind'); if (0 === $propfinds->count()) { throw new ParseRequestException('any propfind element found'); } if (1 < $propfinds->count()) { throw new ParseRequestException('too much propfind element found'); } $propfind = $propfinds->item(0); if (0 === $propfind->childNodes->count()) { throw new ParseRequestException('no element under propfind'); } $unknows = []; $props = []; foreach ($propfind->childNodes->getIterator() as $prop) { /** @var \DOMNode $prop */ if (XML_ELEMENT_NODE !== $prop->nodeType) { continue; } if ('propname' === $prop->nodeName) { return $this->baseProps(true); } foreach ($prop->childNodes->getIterator() as $getProp) { if (XML_ELEMENT_NODE !== $getProp->nodeType) { continue; } if ('DAV:' !== $getProp->lookupNamespaceURI(null)) { $unknows[] = ['xmlns' => $getProp->lookupNamespaceURI(null), 'prop' => $getProp->nodeName]; continue; } $props[] = match ($getProp->nodeName) { 'resourcetype' => 'resourceType', 'getcontenttype' => 'contentType', 'getlastmodified' => 'lastModified', default => '', }; } } $props = array_filter(array_values($props), fn (string $item) => '' !== $item); return [...$this->baseProps(false), ...array_combine($props, array_fill(0, count($props), true)), 'unknowns' => $unknows]; } /** * @return davProperties */ private function baseProps(bool $default = false): array { return [ ...array_combine( self::KNOWN_PROPS, array_fill(0, count(self::KNOWN_PROPS), $default) ), 'unknowns' => [], ]; } }