tree = $server->tree; $server->on('propFind', $this->propFind(...)); $server->on('propPatch', $this->handleUpdateProperties(...)); } public function propFind(PropFind $propFind, INode $node): void { if ($node instanceof AlbumPhoto || $node instanceof PlacePhoto) { // Checking if the node is truly available and ignoring if not // Should be pre-emptively handled by the NodeDeletedEvent try { $fileInfo = $node->getFileInfo(); } catch (NotFoundException) { return; } $propFind->handle(FilesPlugin::INTERNAL_FILEID_PROPERTYNAME, fn (): int => $node->getFile()->getFileId()); $propFind->handle(FilesPlugin::GETETAG_PROPERTYNAME, fn () => $node->getETag()); $propFind->handle(self::FILE_NAME_PROPERTYNAME, fn (): string => $node->getFile()->getName()); $propFind->handle(self::FAVORITE_PROPERTYNAME, fn (): int => $node->isFavorite() ? 1 : 0); $propFind->handle(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, fn () => json_encode($this->previewManager->isAvailable($fileInfo))); $propFind->handle(FilesPlugin::PERMISSIONS_PROPERTYNAME, function () use ($node): string { $permissions = DavUtil::getDavPermissions($node->getFileInfo()); $filteredPermissions = str_replace('R', '', $permissions); if ($node instanceof PublicAlbumPhoto) { $filteredPermissions = str_replace('D', '', $filteredPermissions); $filteredPermissions = str_replace('NV', '', $filteredPermissions); $filteredPermissions = str_replace('W', '', $filteredPermissions); } return $filteredPermissions; }); foreach ($node->getFileInfo()->getMetadata() as $metadataKey => $metadataValue) { $propFind->handle(FilesPlugin::FILE_METADATA_PREFIX . $metadataKey, $metadataValue); } $propFind->handle(FilesPlugin::HIDDEN_PROPERTYNAME, function () use ($node) { $metadata = $this->filesMetadataManager->getMetadata((int)$node->getFileInfo()->getId(), true); return $metadata->hasKey('files-live-photo') && $node->getFileInfo()->getMimetype() === 'video/quicktime' ? 'true' : 'false'; }); $propFind->handle(self::PHOTOS_ALBUM_FILE_ORIGIN_PROPERTYNAME, function () use ($node) { $file = $node->getFile(); if ($file instanceof AlbumFile) { return $file->origin; } else { return null; } }); $propFind->handle(self::PHOTOS_COLLECTION_FILE_ORIGINAL_FILENAME_PROPERTYNAME, function () use ($node) { if (!($node instanceof AlbumPhoto)) { return; } $currentUser = $this->userSession->getUser(); $fileOwner = $node->getFileInfo()->getOwner(); if ($currentUser !== null && $currentUser === $fileOwner) { $userFolder = $this->rootFolder->getUserFolder($currentUser->getUID()); return $userFolder->getRelativePath($node->getFileInfo()->getPath()); } }); } if ($node instanceof ICollection) { $propFind->handle(self::NBITEMS_PROPERTYNAME, fn (): int => count($node->getChildren())); } if ($node instanceof AlbumRootBase) { $propFind->handle(self::ORIGINAL_NAME_PROPERTYNAME, fn (): string => $node->getAlbum()->getAlbum()->getTitle()); $propFind->handle(self::LAST_PHOTO_PROPERTYNAME, fn (): int => $node->getCover()); $propFind->handle(self::LOCATION_PROPERTYNAME, fn (): string => $node->getAlbum()->getAlbum()->getLocation()); $propFind->handle(self::DATE_RANGE_PROPERTYNAME, fn () => json_encode($node->getDateRange())); $propFind->handle(self::COLLABORATORS_PROPERTYNAME, fn (): array => $node->getCollaborators()); $propFind->handle(self::FILTERS_PROPERTYNAME, fn (): ?string => $node->getFilters()); } if ($node instanceof PlaceRoot) { $propFind->handle(self::LAST_PHOTO_PROPERTYNAME, fn (): int => $node->getFirstPhoto()); } } public function handleUpdateProperties($path, PropPatch $propPatch): void { $node = $this->tree->getNodeForPath($path); if ($node instanceof AlbumRootBase) { $propPatch->handle(self::LOCATION_PROPERTYNAME, function ($location) use ($node) { if ($location instanceof Complex) { $location = $location->getXml(); } $node->setLocation($location); return true; }); $propPatch->handle(self::COLLABORATORS_PROPERTYNAME, function ($collaborators) use ($node) { $node->setCollaborators(json_decode($collaborators, true)); return true; }); $propPatch->handle(self::FILTERS_PROPERTYNAME, function ($filters) use ($node) { $node->setFilters($filters); return true; }); } if ($node instanceof AlbumPhoto) { $propPatch->handle(self::FAVORITE_PROPERTYNAME, function ($favoriteState) use ($node) { if ($this->userSession->getUser() !== $node->getFileInfo()->getOwner()) { throw new Forbidden('Only the owner can favorite its photos'); } $node->setFavoriteState($favoriteState); return true; }); } } }