This commit is contained in:
Robin Appelman 2022-04-08 17:28:32 +02:00
commit 4d51484de3
22 changed files with 103 additions and 72 deletions

View file

@ -21,7 +21,6 @@
namespace SearchDAV\Backend;
use Sabre\DAV\INode;
class SearchResult {

View file

@ -33,19 +33,19 @@ use SearchDAV\XML\Scope;
class QueryParser extends Service {
public $namespaceMap = [
'DAV:' => 'd',
'http://sabredav.org/ns' => 's',
'DAV:' => 'd',
'http://sabredav.org/ns' => 's',
'http://www.w3.org/2001/XMLSchema' => 'xs',
SearchPlugin::SEARCHDAV_NS => 'sd'
SearchPlugin::SEARCHDAV_NS => 'sd'
];
public function __construct() {
$this->elementMap = [
'{DAV:}literal' => Literal::class,
'{DAV:}searchrequest' => Element\KeyValue::class,
'{DAV:}literal' => Literal::class,
'{DAV:}searchrequest' => Element\KeyValue::class,
'{DAV:}query-schema-discovery' => Element\KeyValue::class,
'{DAV:}basicsearch' => BasicSearch::class,
'{DAV:}select' => function (Reader $reader) {
'{DAV:}basicsearch' => BasicSearch::class,
'{DAV:}select' => function (Reader $reader) {
return \Sabre\Xml\Deserializer\keyValue($reader, '{DAV:}scope')['{DAV:}prop'];
},
'{DAV:}from' => function (Reader $reader) {
@ -61,20 +61,20 @@ class QueryParser extends Service {
}, $reader->parseGetElements());
return (isset($operators[0])) ? $operators[0] : null;
},
'{DAV:}prop' => Element\Elements::class,
'{DAV:}order' => Order::class,
'{DAV:}eq' => Operator::class,
'{DAV:}gt' => Operator::class,
'{DAV:}gte' => Operator::class,
'{DAV:}lt' => Operator::class,
'{DAV:}lte' => Operator::class,
'{DAV:}and' => Operator::class,
'{DAV:}or' => Operator::class,
'{DAV:}like' => Operator::class,
'{DAV:}contains' => Operator::class,
'{DAV:}not' => Operator::class,
'{DAV:}prop' => Element\Elements::class,
'{DAV:}order' => Order::class,
'{DAV:}eq' => Operator::class,
'{DAV:}gt' => Operator::class,
'{DAV:}gte' => Operator::class,
'{DAV:}lt' => Operator::class,
'{DAV:}lte' => Operator::class,
'{DAV:}and' => Operator::class,
'{DAV:}or' => Operator::class,
'{DAV:}like' => Operator::class,
'{DAV:}contains' => Operator::class,
'{DAV:}not' => Operator::class,
'{DAV:}is-collection' => Operator::class,
'{DAV:}limit' => Limit::class,
'{DAV:}limit' => Limit::class,
];
}
}

View file

@ -85,8 +85,10 @@ class SearchHandler {
$response->setBody($e->getMessage());
return false;
}
$data = $this->server->generateMultiStatus(iterator_to_array($this->getPropertiesIteratorResults($results,
$query->select)), false);
$data = $this->server->generateMultiStatus(iterator_to_array($this->getPropertiesIteratorResults(
$results,
$query->select
)), false);
$response->setBody($data);
return false;
}

View file

@ -21,7 +21,6 @@
namespace SearchDAV\Query;
class Limit {
/**
* @var integer

View file

@ -21,7 +21,6 @@
namespace SearchDAV\Query;
class Literal {
/**
* @var string|boolean|\DateTime|integer

View file

@ -21,7 +21,6 @@
namespace SearchDAV\Query;
use SearchDAV\Backend\SearchPropertyDefinition;
class Order {

View file

@ -21,7 +21,6 @@
namespace SearchDAV\Query;
use SearchDAV\Backend\SearchPropertyDefinition;
class Query {

View file

@ -21,7 +21,6 @@
namespace SearchDAV\Query;
class Scope {
/**
* @var string

View file

@ -70,7 +70,7 @@ class BasicSearch implements XmlDeserializable {
* @return BasicSearch
* @throws ParseException
*/
static function xmlDeserialize(Reader $reader): BasicSearch {
public static function xmlDeserialize(Reader $reader): BasicSearch {
$search = new self();
$elements = \Sabre\Xml\Deserializer\keyValue($reader);

View file

@ -21,7 +21,6 @@
namespace SearchDAV\XML;
use Sabre\Xml\Writer;
use Sabre\Xml\XmlSerializable;
@ -38,10 +37,10 @@ class BasicSearchSchema implements XmlSerializable {
$this->properties = $properties;
}
function xmlSerialize(Writer $writer) {
$childs = array_map(function(PropDesc $propDesc) {
public function xmlSerialize(Writer $writer) {
$childs = array_map(function (PropDesc $propDesc) {
return [
'name' => '{DAV:}propdesc',
'name' => '{DAV:}propdesc',
'value' => $propDesc
];
}, $this->properties);

View file

@ -29,7 +29,7 @@ use SearchDAV\DAV\SearchPlugin;
* The limit and offset of a search query
*/
class Limit extends \SearchDAV\Query\Limit implements XmlDeserializable {
static function xmlDeserialize(Reader $reader): Limit {
public static function xmlDeserialize(Reader $reader): Limit {
$limit = new self();
$elements = \Sabre\Xml\Deserializer\keyValue($reader);

View file

@ -21,12 +21,11 @@
namespace SearchDAV\XML;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
class Literal extends \SearchDAV\Query\Literal implements XmlDeserializable {
static function xmlDeserialize(Reader $reader): Literal {
public static function xmlDeserialize(Reader $reader): Literal {
$literal = new self();
if ($reader->isEmptyElement) {

View file

@ -56,7 +56,7 @@ class Operator implements XmlDeserializable {
$this->arguments = $arguments;
}
static function xmlDeserialize(Reader $reader): Operator {
public static function xmlDeserialize(Reader $reader): Operator {
$operator = new self();
$operator->type = $reader->getClark() ?? '';

View file

@ -21,7 +21,6 @@
namespace SearchDAV\XML;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
@ -50,7 +49,7 @@ class Order implements XmlDeserializable {
$this->order = $order;
}
static function xmlDeserialize(Reader $reader): Order {
public static function xmlDeserialize(Reader $reader): Order {
$order = new self();
$childs = \Sabre\Xml\Deserializer\keyValue($reader);

View file

@ -21,7 +21,6 @@
namespace SearchDAV\XML;
use Sabre\Xml\Writer;
use Sabre\Xml\XmlSerializable;
@ -47,7 +46,7 @@ class PropDesc implements XmlSerializable {
*/
public $sortable;
function xmlSerialize(Writer $writer) {
public function xmlSerialize(Writer $writer) {
$data = [
'{DAV:}dataType' => [$this->dataType => null]
];
@ -62,7 +61,7 @@ class PropDesc implements XmlSerializable {
}
$writer->write(array_map(function ($propName) {
return [
'name' => '{DAV:}prop',
'name' => '{DAV:}prop',
'value' => $propName
];
}, $this->properties));

View file

@ -21,7 +21,6 @@
namespace SearchDAV\XML;
use Sabre\DAV\Xml\Element\Response;
use Sabre\Xml\Writer;
@ -38,16 +37,15 @@ class QueryDiscoverResponse extends Response {
* @param BasicSearchSchema|null $schema
* @param null|int|string $httpStatus
*/
function __construct($href, BasicSearchSchema $schema = null, $httpStatus = null) {
public function __construct($href, BasicSearchSchema $schema = null, $httpStatus = null) {
if ($httpStatus !== null) {
$httpStatus = (string)$httpStatus;
}
parent::__construct($href, [], $httpStatus);
$this->schema = $schema;
}
function xmlSerialize(Writer $writer) {
public function xmlSerialize(Writer $writer) {
if ($status = $this->getHTTPStatus()) {
$writer->writeElement('{DAV:}status', 'HTTP/1.1 ' . $status . ' ' . \Sabre\HTTP\Response::$statusCodes[$status]);
}
@ -55,7 +53,7 @@ class QueryDiscoverResponse extends Response {
if ($this->schema) {
$writer->writeElement('{DAV:}query-schema', [
'{DAV:}basicsearchschema' => $this->schema
'{DAV:}basicsearchschema' => $this->schema
]);
}
}

View file

@ -25,7 +25,7 @@ use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
class Scope extends \SearchDAV\Query\Scope implements XmlDeserializable {
static function xmlDeserialize(Reader $reader): Scope {
public static function xmlDeserialize(Reader $reader): Scope {
$scope = new self();
$values = \Sabre\Xml\Deserializer\keyValue($reader);

View file

@ -21,7 +21,6 @@
namespace SearchDAV\XML;
use Sabre\Xml\Writer;
use Sabre\Xml\XmlSerializable;
@ -30,7 +29,7 @@ class SupportedQueryGrammar implements XmlSerializable {
public $grammar = self::GRAMMAR_BASICSEARCH;
function xmlSerialize(Writer $writer) {
public function xmlSerialize(Writer $writer) {
$writer->startElement('{DAV:}supported-query-grammar');
$writer->startElement('{DAV:}grammar');
$writer->startElement($this->grammar);

View file

@ -54,6 +54,5 @@ class DummyBackend implements ISearchBackend {
}
public function preloadPropertyFor(array $nodes, array $requestProperties): void {
}
}

View file

@ -26,7 +26,7 @@ use Sabre\DAV\Server;
use SearchDAV\DAV\PathHelper;
class PathHelperTest extends TestCase {
public function uriProvider(){
public function uriProvider() {
return [
['/', '', ''],
['/index.php/', 'foo', 'foo'],

View file

@ -33,7 +33,6 @@ use SearchDAV\XML\Order;
use SearchDAV\XML\Scope;
use SearchDAV\XML\SupportedQueryGrammar;
class QueryParserTest extends TestCase {
public function testParseBasicQuery() {
$query = file_get_contents(__DIR__ . '/basicquery.xml');

View file

@ -180,12 +180,22 @@ class SearchPluginTest extends TestCase {
$this->searchBackend->expects($this->once())
->method('getPropertyDefinitionsForScope')
->willReturn([
new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition(
'{DAV:}getcontentlength',
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_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_NONNEGATIVE_INTEGER
),
]);
$plugin->searchHandler($request, $response);
@ -274,8 +284,13 @@ class SearchPluginTest extends TestCase {
->method('isValidScope')
->willReturn(true);
$lengthProp = new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER);
$lengthProp = new SearchPropertyDefinition(
'{DAV:}getcontentlength',
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
);
$orderBy = [
new \SearchDAV\Query\Order($lengthProp, \SearchDAV\Query\Order::ASC),
];
@ -347,8 +362,13 @@ class SearchPluginTest extends TestCase {
->method('getArbiterPath')
->willReturn('foo');
$lengthProp = new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER);
$lengthProp = new SearchPropertyDefinition(
'{DAV:}getcontentlength',
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
);
$plugin = new SearchPlugin($this->searchBackend);
$server = new Server();
$plugin->initialize($server);
@ -483,8 +503,13 @@ class SearchPluginTest extends TestCase {
$this->searchBackend->expects($this->once())
->method('getPropertyDefinitionsForScope')
->willReturn([
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_NONNEGATIVE_INTEGER
),
]);
$plugin->searchHandler($request, $response);
@ -518,10 +543,20 @@ class SearchPluginTest extends TestCase {
$this->searchBackend->expects($this->any())
->method('getPropertyDefinitionsForScope')
->willReturn([
new SearchPropertyDefinition('{http://ns.nextcloud.com:}fileid', false, true, true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition(
'{http://ns.nextcloud.com:}fileid',
false,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
),
new SearchPropertyDefinition(
'{DAV:}getcontentlength',
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
),
]);
$plugin->searchHandler($request, $response);
@ -555,15 +590,24 @@ class SearchPluginTest extends TestCase {
$this->searchBackend->expects($this->any())
->method('getPropertyDefinitionsForScope')
->willReturn([
new SearchPropertyDefinition('{http://ns.nextcloud.com:}fileid', false, true, true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
new SearchPropertyDefinition(
'{http://ns.nextcloud.com:}fileid',
false,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
),
new SearchPropertyDefinition(
'{DAV:}getcontentlength',
true,
true,
true,
SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER
),
]);
$plugin->searchHandler($request, $response);
$this->assertEquals(400, $response->getStatus());
}
}