mirror of
https://codeberg.org/icewind/SearchDAV.git
synced 2026-06-03 17:44:06 +02:00
Seperate query classes from xml classes to allow specifying more information in the query
This commit is contained in:
parent
82bcf2cebb
commit
5ad4d24b89
17 changed files with 509 additions and 112 deletions
|
|
@ -21,11 +21,16 @@
|
|||
|
||||
namespace SearchDAV\DAV;
|
||||
|
||||
use Sabre\DAV\Exception\BadRequest;
|
||||
use Sabre\DAV\PropFind;
|
||||
use Sabre\DAV\Server;
|
||||
use Sabre\HTTP\ResponseInterface;
|
||||
use SearchDAV\Backend\ISearchBackend;
|
||||
use SearchDAV\Backend\SearchPropertyDefinition;
|
||||
use SearchDAV\Backend\SearchResult;
|
||||
use SearchDAV\Query\Operator;
|
||||
use SearchDAV\Query\Order;
|
||||
use SearchDAV\Query\Query;
|
||||
use SearchDAV\XML\BasicSearch;
|
||||
|
||||
class SearchHandler {
|
||||
|
|
@ -69,15 +74,79 @@ class SearchHandler {
|
|||
}
|
||||
$response->setStatus(207);
|
||||
$response->setHeader('Content-Type', 'application/xml; charset="utf-8"');
|
||||
$allProps = [];
|
||||
foreach ($query->from as $scope) {
|
||||
$scope->path = $this->pathHelper->getPathFromUri($scope->href);
|
||||
$props = $this->searchBackend->getPropertyDefinitionsForScope($scope->href, $scope->path);
|
||||
foreach ($props as $prop) {
|
||||
$allProps[$prop->name] = $prop;
|
||||
}
|
||||
}
|
||||
try {
|
||||
$results = $this->searchBackend->search($this->getQueryForXML($query, $allProps));
|
||||
} catch (BadRequest $e) {
|
||||
$response->setStatus(400);
|
||||
$response->setBody($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
$results = $this->searchBackend->search($query);
|
||||
$data = $this->server->generateMultiStatus(iterator_to_array($this->getPropertiesIteratorResults($results, $query->select)), false);
|
||||
$response->setBody($data);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BasicSearch $xml
|
||||
* @param SearchPropertyDefinition[] $allProps
|
||||
* @return Query
|
||||
*/
|
||||
private function getQueryForXML(BasicSearch $xml, array $allProps) {
|
||||
$orderBy = array_map(function (\SearchDAV\XML\Order $order) use ($allProps) {
|
||||
if (!isset($allProps[$order->property])) {
|
||||
throw new BadRequest('requested order by property is not a valid property for this scope');
|
||||
}
|
||||
$prop = $allProps[$order->property];
|
||||
if (!$prop->sortable) {
|
||||
throw new BadRequest('requested order by property is not sortable');
|
||||
}
|
||||
return new Order($prop, $order->order);
|
||||
}, $xml->orderBy);
|
||||
$select = array_map(function ($propName) use ($allProps) {
|
||||
if (!isset($allProps[$propName])) {
|
||||
throw new BadRequest('requested property is not a valid property for this scope');
|
||||
}
|
||||
$prop = $allProps[$propName];
|
||||
if (!$prop->selectable) {
|
||||
throw new BadRequest('requested property is not selectable');
|
||||
}
|
||||
return $prop;
|
||||
}, $xml->select);
|
||||
|
||||
$where = $this->transformOperator($xml->where, $allProps);
|
||||
|
||||
return new Query($select, $xml->from, $where, $orderBy, $xml->limit);
|
||||
}
|
||||
|
||||
private function transformOperator(\SearchDAV\XML\Operator $operator, array $allProps) {
|
||||
$arguments = array_map(function ($argument) use ($allProps) {
|
||||
if (is_string($argument)) {
|
||||
if (!isset($allProps[$argument])) {
|
||||
throw new BadRequest('requested search property is not a valid property for this scope');
|
||||
}
|
||||
$prop = $allProps[$argument];
|
||||
if (!$prop->searchable) {
|
||||
throw new BadRequest('requested search property is not searchable');
|
||||
}
|
||||
return $prop;
|
||||
} else if ($argument instanceof \SearchDAV\XML\Operator) {
|
||||
return $this->transformOperator($argument, $allProps);
|
||||
} else {
|
||||
return $argument;
|
||||
}
|
||||
}, $operator->arguments);
|
||||
|
||||
return new Operator($operator->type, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of properties for a given path
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue