Skip to content

Commit 5053cc5

Browse files
authored
Merge pull request #39294 from nextcloud/backport/39248/stable25
[stable25] preload custom properties when propfinding folders
2 parents 6715bba + f3d924d commit 5053cc5

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

apps/dav/lib/DAV/CustomPropertiesBackend.php

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
* along with this program. If not, see <http://www.gnu.org/licenses/>
2323
*
2424
*/
25+
2526
namespace OCA\DAV\DAV;
2627

2728
use Exception;
29+
use OCA\DAV\Connector\Sabre\Directory;
2830
use OCP\DB\QueryBuilder\IQueryBuilder;
2931
use OCP\IDBConnection;
3032
use OCP\IUser;
@@ -134,7 +136,8 @@ class CustomPropertiesBackend implements BackendInterface {
134136
public function __construct(
135137
Tree $tree,
136138
IDBConnection $connection,
137-
IUser $user) {
139+
IUser $user
140+
) {
138141
$this->tree = $tree;
139142
$this->connection = $connection;
140143
$this->user = $user;
@@ -180,6 +183,11 @@ public function propFind($path, PropFind $propFind) {
180183
return;
181184
}
182185

186+
$node = $this->tree->getNodeForPath($path);
187+
if ($node instanceof Directory && $propFind->getDepth() !== 0) {
188+
$this->cacheDirectory($path, $node);
189+
}
190+
183191
// First fetch the published properties (set by another user), then get the ones set by
184192
// the current user. If both are set then the latter as priority.
185193
foreach ($this->getPublishedProperties($path, $requestedProps) as $propName => $propValue) {
@@ -262,6 +270,38 @@ private function getPublishedProperties(string $path, array $requestedProperties
262270
return $props;
263271
}
264272

273+
/**
274+
* prefetch all user properties in a directory
275+
*/
276+
private function cacheDirectory(string $path, Directory $node): void {
277+
$prefix = ltrim($path . '/', '/');
278+
$query = $this->connection->getQueryBuilder();
279+
$query->select('name', 'propertypath', 'propertyname', 'propertyvalue', 'valuetype')
280+
->from('filecache', 'f')
281+
->leftJoin('f', 'properties', 'p', $query->expr()->andX(
282+
$query->expr()->eq('propertypath', $query->func()->concat(
283+
$query->createNamedParameter($prefix),
284+
'name'
285+
)),
286+
$query->expr()->eq('userid', $query->createNamedParameter($this->user->getUID()))
287+
))
288+
->where($query->expr()->eq('parent', $query->createNamedParameter($node->getInternalFileId(), IQueryBuilder::PARAM_INT)));
289+
$result = $query->executeQuery();
290+
291+
$propsByPath = [];
292+
293+
while ($row = $result->fetch()) {
294+
$childPath = $prefix . $row['name'];
295+
if (!isset($propsByPath[$childPath])) {
296+
$propsByPath[$childPath] = [];
297+
}
298+
if (isset($row['propertyname'])) {
299+
$propsByPath[$childPath][$row['propertyname']] = $this->decodeValueFromDatabase($row['propertyvalue'], $row['valuetype']);
300+
}
301+
}
302+
$this->userCache = array_merge($this->userCache, $propsByPath);
303+
}
304+
265305
/**
266306
* Returns a list of properties for the given path and current user
267307
*
@@ -321,7 +361,7 @@ private function updateProperties(string $path, array $properties): bool {
321361
$dbParameters = [
322362
'userid' => $this->user->getUID(),
323363
'propertyPath' => $this->formatPath($path),
324-
'propertyName' => $propertyName
364+
'propertyName' => $propertyName,
325365
];
326366

327367
// If it was null, we need to delete the property

0 commit comments

Comments
 (0)