minor fixes

This commit is contained in:
Robin Appelman 2022-04-11 14:52:12 +02:00
commit acb32ab84d
15 changed files with 60 additions and 47 deletions

View file

@ -28,7 +28,7 @@ interface ISearchBackend {
/**
* Get the path of the search arbiter of this backend
*
* The search arbiter is the URI that the client will send it's SEARCH requests to
* The search arbiter is the URI that the client will send its SEARCH requests to
* Note that this is not required to be the same as the search scopes which determine what to search in
*
* The returned value should be a path relative the root of the dav server.
@ -41,7 +41,7 @@ interface ISearchBackend {
public function getArbiterPath(): string;
/**
* Whether or not the search backend supports search requests on this scope
* Whether the search backend supports search requests on this scope
*
* The scope defines the resource that it being searched, such as a folder or address book.
*

View file

@ -25,7 +25,7 @@ class SearchPropertyDefinition {
const XS = '{http://www.w3.org/2001/XMLSchema}';
const DATATYPE_STRING = self::XS . 'string';
const DATATYPE_INTEGER = self::XS . 'integer';
const DATATYPE_NONNEGATIVE_INTEGER = self::XS . 'nonNegativeInteger';
const DATATYPE_NON_NEGATIVE_INTEGER = self::XS . 'nonNegativeInteger';
const DATATYPE_DECIMAL = self::XS . 'decimal';
const DATATYPE_DATETIME = self::XS . 'dateTime';
const DATATYPE_BOOLEAN = self::XS . 'boolean';
@ -48,11 +48,11 @@ class SearchPropertyDefinition {
* SearchProperty constructor.
*
* @param string $name the name and namespace of the property in clark notation
* @param bool $searchable whether or not this property can be used as part of a search query
* @param bool $selectable whether or not this property can be returned as part of a search result
* @param bool $sortable whether or not this property can be used to sort the search result
* @param bool $searchable whether this property can be used as part of a search query
* @param bool $selectable whether this property can be returned as part of a search result
* @param bool $sortable whether this property can be used to sort the search result
* @param string $dataType the datatype of the property, one of the SearchProperty::DATATYPE_ constants or any XSD datatype in clark notation
* @param bool $caseSensitive whether or not comparisons on the property are case sensitive, only applies to string propertries
* @param bool $caseSensitive whether comparisons on the property are case-sensitive, only applies to string properties
*/
public function __construct(string $name, bool $selectable, bool $searchable, bool $sortable, string $dataType = self::DATATYPE_STRING, bool $caseSensitive = true) {
$this->searchable = $searchable;

View file

@ -97,12 +97,7 @@ class DiscoverHandler {
foreach ($propertyDefinitions as $propertyDefinition) {
$key = $this->hashDefinition($propertyDefinition);
if (!isset($groups[$key])) {
$desc = new PropDesc();
$desc->dataType = $propertyDefinition->dataType;
$desc->sortable = $propertyDefinition->sortable;
$desc->selectable = $propertyDefinition->selectable;
$desc->searchable = $propertyDefinition->searchable;
$groups[$key] = $desc;
$groups[$key] = new PropDesc($propertyDefinition);
}
$groups[$key]->properties[] = $propertyDefinition->name;
}

View file

@ -30,6 +30,8 @@ use SearchDAV\XML\Literal;
use SearchDAV\XML\Operator;
use SearchDAV\XML\Order;
use SearchDAV\XML\Scope;
use function Sabre\Xml\Deserializer\keyValue;
use function Sabre\Xml\Deserializer\repeatingElements;
class QueryParser extends Service {
public $namespaceMap = [
@ -46,13 +48,13 @@ class QueryParser extends Service {
'{DAV:}query-schema-discovery' => Element\KeyValue::class,
'{DAV:}basicsearch' => BasicSearch::class,
'{DAV:}select' => function (Reader $reader) {
return \Sabre\Xml\Deserializer\keyValue($reader, '{DAV:}scope')['{DAV:}prop'];
return keyValue($reader, '{DAV:}scope')['{DAV:}prop'];
},
'{DAV:}from' => function (Reader $reader) {
return \Sabre\Xml\Deserializer\repeatingElements($reader, '{DAV:}scope');
return repeatingElements($reader, '{DAV:}scope');
},
'{DAV:}orderby' => function (Reader $reader) {
return \Sabre\Xml\Deserializer\repeatingElements($reader, '{DAV:}order');
return repeatingElements($reader, '{DAV:}order');
},
'{DAV:}scope' => Scope::class,
'{DAV:}where' => function (Reader $reader) {

View file

@ -34,9 +34,6 @@ use SearchDAV\XML\SupportedQueryGrammar;
class SearchPlugin extends ServerPlugin {
const SEARCHDAV_NS = 'https://github.com/icewind1991/SearchDAV/ns';
/** @var Server */
private $server;
/** @var ISearchBackend */
private $searchBackend;
@ -58,7 +55,6 @@ class SearchPlugin extends ServerPlugin {
}
public function initialize(Server $server): void {
$this->server = $server;
$this->pathHelper = new PathHelper($server);
$this->search = new SearchHandler($this->searchBackend, $this->pathHelper, $server);
$this->discover = new DiscoverHandler($this->searchBackend, $this->pathHelper, $this->queryParser);

View file

@ -48,7 +48,7 @@ class Query {
* The list of order operations that should be used to order the results.
*
* Each order operations consists of a property to sort on and a sort direction.
* If more then one order operations are specified, the comparisons for ordering should
* If more than one order operations are specified, the comparisons for ordering should
* be applied in the order that the order operations are defined in with the earlier comparisons being
* more significant.
*/

View file

@ -24,6 +24,7 @@ namespace SearchDAV\XML;
use Sabre\Xml\ParseException;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
use function Sabre\Xml\Deserializer\keyValue;
/**
* The object representation of a search query made by the client
@ -65,26 +66,33 @@ class BasicSearch implements XmlDeserializable {
*/
public $limit;
public function __construct(array $select, array $from, ?Operator $where, array $orderBy, Limit $limit) {
$this->select = $select;
$this->from = $from;
$this->where = $where;
$this->orderBy = $orderBy;
$this->limit = $limit;
}
/**
* @param Reader $reader
* @return BasicSearch
* @throws ParseException
*/
public static function xmlDeserialize(Reader $reader): BasicSearch {
$search = new self();
$elements = \Sabre\Xml\Deserializer\keyValue($reader);
$elements = keyValue($reader);
if (!isset($elements['{DAV:}from'])) {
throw new ParseException('Missing {DAV:}from when parsing {DAV:}basicsearch');
}
$search->select = $elements['{DAV:}select'] ?? [];
$search->from = $elements['{DAV:}from'];
$search->where = $elements['{DAV:}where'] ?? null;
$search->orderBy = $elements['{DAV:}orderby'] ?? [];
$search->limit = $elements['{DAV:}limit'] ?? new Limit();
return $search;
return new BasicSearch(
$elements['{DAV:}select'] ?? [],
$elements['{DAV:}from'],
$elements['{DAV:}where'] ?? null,
$elements['{DAV:}orderby'] ?? [],
$elements['{DAV:}limit'] ?? new Limit()
);
}
}

View file

@ -24,6 +24,7 @@ namespace SearchDAV\XML;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
use SearchDAV\DAV\SearchPlugin;
use function Sabre\Xml\Deserializer\keyValue;
/**
* The limit and offset of a search query
@ -32,7 +33,7 @@ class Limit extends \SearchDAV\Query\Limit implements XmlDeserializable {
public static function xmlDeserialize(Reader $reader): Limit {
$limit = new self();
$elements = \Sabre\Xml\Deserializer\keyValue($reader);
$elements = keyValue($reader);
$namespace = SearchPlugin::SEARCHDAV_NS;
$limit->maxResults = isset($elements['{DAV:}nresults']) ? $elements['{DAV:}nresults'] : 0;

View file

@ -23,6 +23,7 @@ namespace SearchDAV\XML;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
use function Sabre\Xml\Deserializer\keyValue;
class Order implements XmlDeserializable {
/**
@ -52,7 +53,7 @@ class Order implements XmlDeserializable {
public static function xmlDeserialize(Reader $reader): Order {
$order = new self();
$childs = \Sabre\Xml\Deserializer\keyValue($reader);
$childs = keyValue($reader);
$order->order = array_key_exists('{DAV:}descending', $childs) ? \SearchDAV\Query\Order::DESC : \SearchDAV\Query\Order::ASC;
$order->property = $childs['{DAV:}prop'][0];

View file

@ -23,6 +23,7 @@ namespace SearchDAV\XML;
use Sabre\Xml\Writer;
use Sabre\Xml\XmlSerializable;
use SearchDAV\Backend\SearchPropertyDefinition;
class PropDesc implements XmlSerializable {
/**
@ -46,6 +47,13 @@ class PropDesc implements XmlSerializable {
*/
public $sortable;
public function __construct(SearchPropertyDefinition $propertyDefinition) {
$this->dataType = $propertyDefinition->dataType;
$this->sortable = $propertyDefinition->sortable;
$this->selectable = $propertyDefinition->selectable;
$this->searchable = $propertyDefinition->searchable;
}
public function xmlSerialize(Writer $writer): void {
$data = [
'{DAV:}dataType' => [$this->dataType => null]

View file

@ -23,6 +23,7 @@ namespace SearchDAV\XML;
use Sabre\DAV\Xml\Element\Response;
use Sabre\Xml\Writer;
use function Sabre\HTTP\encodePath;
class QueryDiscoverResponse extends Response {
/**
@ -49,7 +50,7 @@ class QueryDiscoverResponse extends Response {
if ($status = $this->getHTTPStatus()) {
$writer->writeElement('{DAV:}status', 'HTTP/1.1 ' . $status . ' ' . \Sabre\HTTP\Response::$statusCodes[$status]);
}
$writer->writeElement('{DAV:}href', \Sabre\HTTP\encodePath($this->getHref()));
$writer->writeElement('{DAV:}href', encodePath($this->getHref()));
if ($this->schema) {
$writer->writeElement('{DAV:}query-schema', [

View file

@ -23,12 +23,13 @@ namespace SearchDAV\XML;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
use function Sabre\Xml\Deserializer\keyValue;
class Scope extends \SearchDAV\Query\Scope implements XmlDeserializable {
public static function xmlDeserialize(Reader $reader): Scope {
$scope = new self();
$values = \Sabre\Xml\Deserializer\keyValue($reader);
$values = keyValue($reader);
$scope->href = $values['{DAV:}href'];
$scope->depth = $values['{DAV:}depth'];

View file

@ -40,10 +40,10 @@ class DummyBackend implements ISearchBackend {
public function getPropertyDefinitionsForScope($href, $path): array {
return [
new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true, SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER),
new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true),
new SearchPropertyDefinition('{DAV:}displayname', true, true, true),
new SearchPropertyDefinition('{http://ns.nextcloud.com:}fileid', false, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition('{http://ns.nextcloud.com:}fileid', false, true, true, SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER),
];
}

View file

@ -185,7 +185,7 @@ class SearchPluginTest extends TestCase {
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
),
new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true),
new SearchPropertyDefinition('{DAV:}displayname', true, true, true),
@ -194,7 +194,7 @@ class SearchPluginTest extends TestCase {
false,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
),
]);
@ -289,7 +289,7 @@ class SearchPluginTest extends TestCase {
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
);
$orderBy = [
new \SearchDAV\Query\Order($lengthProp, \SearchDAV\Query\Order::ASC),
@ -367,7 +367,7 @@ class SearchPluginTest extends TestCase {
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
);
$plugin = new SearchPlugin($this->searchBackend);
$server = new Server();
@ -508,7 +508,7 @@ class SearchPluginTest extends TestCase {
false,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
),
]);
@ -548,14 +548,14 @@ class SearchPluginTest extends TestCase {
false,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
),
new SearchPropertyDefinition(
'{DAV:}getcontentlength',
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
),
]);
@ -595,14 +595,14 @@ class SearchPluginTest extends TestCase {
false,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
),
new SearchPropertyDefinition(
'{DAV:}getcontentlength',
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
SearchPropertyDefinition::DATATYPE_NON_NEGATIVE_INTEGER
),
]);