aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------3rdparty0
-rw-r--r--apps/dav/lib/CalDAV/CachedSubscription.php4
-rw-r--r--apps/dav/lib/Files/FileSearchBackend.php31
-rw-r--r--build/integration/features/bootstrap/CommentsContext.php36
-rw-r--r--lib/private/Files/Cache/SearchBuilder.php2
-rw-r--r--lib/public/Files/Search/ISearchComparison.php1
6 files changed, 61 insertions, 13 deletions
diff --git a/3rdparty b/3rdparty
-Subproject d7b9f6f5f0513adc3ed652eb84b1822fb5b5303
+Subproject b3d52b32c65999204aefeb85548f95c76391d63
diff --git a/apps/dav/lib/CalDAV/CachedSubscription.php b/apps/dav/lib/CalDAV/CachedSubscription.php
index dc7f66e59b4..4047f8dad0b 100644
--- a/apps/dav/lib/CalDAV/CachedSubscription.php
+++ b/apps/dav/lib/CalDAV/CachedSubscription.php
@@ -169,11 +169,11 @@ class CachedSubscription extends \Sabre\CalDAV\Calendar {
/**
* @param string $name
- * @param null|resource|string $calendarData
+ * @param null|resource|string $data
* @return null|string
* @throws MethodNotAllowed
*/
- public function createFile($name, $calendarData = null) {
+ public function createFile($name, $data = null) {
throw new MethodNotAllowed('Creating objects in cached subscription is not allowed');
}
diff --git a/apps/dav/lib/Files/FileSearchBackend.php b/apps/dav/lib/Files/FileSearchBackend.php
index 3500d6b0fb3..419a0c5ed3b 100644
--- a/apps/dav/lib/Files/FileSearchBackend.php
+++ b/apps/dav/lib/Files/FileSearchBackend.php
@@ -39,6 +39,7 @@ use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
+use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchOrder;
use OCP\Files\Search\ISearchQuery;
@@ -367,22 +368,30 @@ class FileSearchBackend implements ISearchBackend {
if (count($operator->arguments) !== 2) {
throw new \InvalidArgumentException('Invalid number of arguments for ' . $trimmedType . ' operation');
}
- if (!($operator->arguments[0] instanceof SearchPropertyDefinition)) {
- throw new \InvalidArgumentException('Invalid argument 1 for ' . $trimmedType . ' operation, expected property');
- }
if (!($operator->arguments[1] instanceof Literal)) {
throw new \InvalidArgumentException('Invalid argument 2 for ' . $trimmedType . ' operation, expected literal');
}
-
+ $value = $operator->arguments[1]->value;
+ case Operator::OPERATION_IS_DEFINED:
+ if (!($operator->arguments[0] instanceof SearchPropertyDefinition)) {
+ throw new \InvalidArgumentException('Invalid argument 1 for ' . $trimmedType . ' operation, expected property');
+ }
$property = $operator->arguments[0];
- $value = $this->castValue($property, $operator->arguments[1]->value);
+
if (str_starts_with($property->name, FilesPlugin::FILE_METADATA_PREFIX)) {
- return new SearchComparison($trimmedType, substr($property->name, strlen(FilesPlugin::FILE_METADATA_PREFIX)), $value, IMetadataQuery::EXTRA);
+ $field = substr($property->name, strlen(FilesPlugin::FILE_METADATA_PREFIX));
+ $extra = IMetadataQuery::EXTRA;
} else {
- return new SearchComparison($trimmedType, $this->mapPropertyNameToColumn($property), $value);
+ $field = $this->mapPropertyNameToColumn($property);
}
- // no break
+ return new SearchComparison(
+ $trimmedType,
+ $field,
+ $this->castValue($property, $value ?? ''),
+ $extra ?? ''
+ );
+
case Operator::OPERATION_IS_COLLECTION:
return new SearchComparison('eq', 'mimetype', ICacheEntry::DIRECTORY_MIMETYPE);
default:
@@ -416,7 +425,11 @@ class FileSearchBackend implements ISearchBackend {
}
private function castValue(SearchPropertyDefinition $property, $value) {
- switch ($property->dataType) {
+ if ($value === '') {
+ return '';
+ }
+
+ switch ($property->dataType) {
case SearchPropertyDefinition::DATATYPE_BOOLEAN:
return $value === 'yes';
case SearchPropertyDefinition::DATATYPE_DECIMAL:
diff --git a/build/integration/features/bootstrap/CommentsContext.php b/build/integration/features/bootstrap/CommentsContext.php
index ad2d752b4dd..989f34692ca 100644
--- a/build/integration/features/bootstrap/CommentsContext.php
+++ b/build/integration/features/bootstrap/CommentsContext.php
@@ -49,6 +49,37 @@ class CommentsContext implements \Behat\Behat\Context\Context {
}
}
+
+
+ /**
+ * get a named entry from response instead of picking a random entry from values
+ *
+ * @param string $path
+ *
+ * @return array|string
+ * @throws Exception
+ */
+ private function getValueFromNamedEntries(string $path, array $response): mixed {
+ $next = '';
+ if (str_contains($path, ' ')) {
+ [$key, $next] = explode(' ', $path, 2);
+ } else {
+ $key = $path;
+ }
+
+ foreach ($response as $entry) {
+ if ($entry['name'] === $key) {
+ if ($next !== '') {
+ return $this->getValueFromNamedEntries($next, $entry['value']);
+ } else {
+ return $entry['value'];
+ }
+ }
+ }
+
+ return null;
+ }
+
/** @AfterScenario */
public function teardownScenario() {
$client = new \GuzzleHttp\Client();
@@ -175,7 +206,7 @@ class CommentsContext implements \Behat\Behat\Context\Context {
if ($res->getStatusCode() === 207) {
$service = new Sabre\Xml\Service();
$this->response = $service->parse($res->getBody()->getContents());
- $this->commentId = (int) ($this->response[0]['value'][2]['value'][0]['value'][0]['value'] ?? 0);
+ $this->commentId = (int) ($this->getValueFromNamedEntries('{DAV:}response {DAV:}propstat {DAV:}prop {http://owncloud.org/ns}id', $this->response ?? []) ?? 0);
}
}
@@ -238,7 +269,8 @@ class CommentsContext implements \Behat\Behat\Context\Context {
* @throws \Exception
*/
public function theResponseShouldContainAPropertyWithValue($key, $value) {
- $keys = $this->response[0]['value'][2]['value'][0]['value'];
+// $keys = $this->response[0]['value'][1]['value'][0]['value'];
+ $keys = $this->getValueFromNamedEntries('{DAV:}response {DAV:}propstat {DAV:}prop', $this->response);
$found = false;
foreach ($keys as $singleKey) {
if ($singleKey['name'] === '{http://owncloud.org/ns}' . substr($key, 3)) {
diff --git a/lib/private/Files/Cache/SearchBuilder.php b/lib/private/Files/Cache/SearchBuilder.php
index c3699cca63d..38161ec9cc6 100644
--- a/lib/private/Files/Cache/SearchBuilder.php
+++ b/lib/private/Files/Cache/SearchBuilder.php
@@ -47,6 +47,7 @@ class SearchBuilder {
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'gte',
ISearchComparison::COMPARE_LESS_THAN => 'lt',
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte',
+ ISearchComparison::COMPARE_DEFINED => 'isNotNull',
];
protected static $searchOperatorNegativeMap = [
@@ -57,6 +58,7 @@ class SearchBuilder {
ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'lt',
ISearchComparison::COMPARE_LESS_THAN => 'gte',
ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'gt',
+ ISearchComparison::COMPARE_DEFINED => 'isNull',
];
public const TAG_FAVORITE = '_$!<Favorite>!$_';
diff --git a/lib/public/Files/Search/ISearchComparison.php b/lib/public/Files/Search/ISearchComparison.php
index d7313fbaf2a..ba02f39996f 100644
--- a/lib/public/Files/Search/ISearchComparison.php
+++ b/lib/public/Files/Search/ISearchComparison.php
@@ -35,6 +35,7 @@ interface ISearchComparison extends ISearchOperator {
public const COMPARE_LESS_THAN_EQUAL = 'lte';
public const COMPARE_LIKE = 'like';
public const COMPARE_LIKE_CASE_SENSITIVE = 'clike';
+ public const COMPARE_DEFINED = 'is-defined';
public const HINT_PATH_EQ_HASH = 'path_eq_hash'; // transform `path = "$path"` into `path_hash = md5("$path")`, on by default