mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-28 18:43:49 +00:00
Webdav: fully implements the controller and response
The controller is tested from real request scraped from apache mod_dav implementation. The requests were scraped using a wireshark-like tool. Those requests have been adapted to suit to our xml.
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\DocStoreBundle\Dav\Request;
|
||||
|
||||
use Chill\DocStoreBundle\Dav\Exception\ParseRequestException;
|
||||
|
||||
/**
|
||||
* @phpstan-type davProperties array{resourceType: bool, contentType: bool, lastModified: bool, creationDate: bool, contentLength: bool, etag: bool, supportedLock: bool, unknowns: list<array{xmlns: string, prop: string}>}
|
||||
*/
|
||||
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' => []
|
||||
];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user