Skip to content

feat: register file attributes once for WebDAV and PHP - #65397

Open
skjnldsv wants to merge 3 commits into
masterfrom
feature/node-attribute-providers
Open

skjnldsv wants to merge 3 commits into
masterfrom
feature/node-attribute-providers

Conversation

@skjnldsv

@skjnldsv skjnldsv commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Summary

Today only a PROPFIND gives you a complete file: favorite, has-preview, share-types etc all come from Sabre plugins. Apps that return files from their own endpoints (Deck, Recommendations, Talk, OpenProject...) each rebuild a partial version, with their own keys.

This adds a registry for attribute providers. A generic DAV plugin and a PHP serializer (INodeSerializer) both read from it, so you get the same data from the same code either way. The new code is the registry, serializer and plugin, the dedup comes as existing plugins move over.

First commit is the API, the second moves has-preview and favorite as the first two. Details in the RFC.

Worth a look:

  • a logged in user on a public link doesnt get favorite anymore, public endpoints use the share as context
  • FilesPlugin and ServerFactory no longer take IPreview

Not in here: share attributes (#65400) and dataToNode() in @nextcloud/files. Psalm not checked locally yet.

TODO

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

👾 This pull request was assisted by Claude Code, commits carry an Assisted-by trailer.

@skjnldsv skjnldsv added this to the Nextcloud 36 milestone Oct 11, 2026
@skjnldsv skjnldsv self-assigned this Oct 11, 2026
@skjnldsv skjnldsv added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Oct 14, 2026
@skjnldsv
skjnldsv marked this pull request as ready for review October 14, 2026 09:19
@skjnldsv
skjnldsv requested a review from a team as a code owner October 14, 2026 09:19
@skjnldsv
skjnldsv requested review from Altahrim, come-nc, provokateurin and sorbaugh and removed request for a team October 14, 2026 09:19
@skjnldsv
skjnldsv added this pull request to stack #65494 October 14, 2026 09:27

@susnux susnux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This must go through proper planning, it looks very AI generated, which is not bad but tend to not meet our stability requirements (this API needs to be stable for 5+ years)
  2. This is missing proper handling of duplicates, what if two apps have the same attribute? How to override one if you need to? How to handle clashes? Maybe keep namespaces (we only do not use them in the frontend because the webdav js library does not use it, but its likely something we need with further growth of Nextcloud)
  3. This is potential changing API, it must not go straight into OCP but first NCU

@skjnldsv

skjnldsv commented Oct 16, 2026 •

Copy link
Copy Markdown
Member Author
  1. This is missing proper handling of duplicates, what if two apps have the same attribute? How to override one if you need to? How to handle clashes? Maybe keep namespaces (we only do not use them in the frontend because the webdav js library does not use it, but its likely something we need with further growth of Nextcloud)

I’d forbid it on purpose in v1. I think this is still not something we actually use and for now I don't think we should go for it. If we wanna improve in the future, why not
EDIT: only one place I could actually find uses overriding btw, richdocuments with the secure view and hide-download. Which is now supposed to be removed as hide-download is legacy sharing

  1. This is potential changing API, it must not go straight into OCP but first NCU

If you feel more at ease with that, no problem for me :)

  1. This must go through proper planning, it looks very AI generated, which is not bad but tend to not meet our stability requirements

This is AI assisted, but not fully generated no. The change is really not that big, stability is not about how it's been coded but about proper reviews, which I've yet to actually see 😉

Apps register INodeAttributeProvider with the attributes they serve, in
Clark notation. INodeSerializer returns nodes with those attributes in
the shape @nextcloud/files uses, so PHP code gets the same file data as
a PROPFIND.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: John Molakvoæ <14975046+skjnldsv@users.noreply.github.com>
…providers

A Sabre plugin serves the registered attributes on remote.php, /webdav
and the public endpoints, preloading collections and search results at
once. has-preview and favorite move from FilesPlugin and TagsPlugin to
providers, so WebDAV and the serializer share one implementation.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: John Molakvoæ <14975046+skjnldsv@users.noreply.github.com>
@skjnldsv
skjnldsv force-pushed the feature/node-attribute-providers branch from 346f738 to defcdf7 Compare October 16, 2026 16:15

$fileIds = array_values(array_filter(
array_map(static fn (Node $node): int => $node->getId(), $nodes),
fn (int $fileId): bool => !isset($this->favorites[$userId][$fileId]),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can $this->favorites[$userId][$fileId] be set at this point, the only set I see is below on line 47?
Can preload be called several times?

Each provider has to handle its own preloading? Is there no way to upstream this logic?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it can be called several times in the same request. The serializer always calls it, so two serialize() on the same nodes would reload them, and getAttributes() falls back to preload() if a node wasnt preloaded. Over DAV the plugin already skips them so it never matches there.

The provider has to keep its results anyway between preload() and getAttributes(). The "skip what's already loaded" bit could move up to the serializer/plugin though, I can do that if you prefer 👍

@come-nc

come-nc commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

It’s hard for me to grasp what this is about.
Description sounds like de-duplication but it adds a lot of code.

The second commit is an example of migrating an app to the new api or is it more than this? It feels like it’s mixed with implementing the API.

It’s an issue that NodeAttributeRegistry is used in OCA while defined in OC, it needs a public API or it should be moved to apps/dav if it’s only used there, not clear to me.

@skjnldsv

Copy link
Copy Markdown
Member Author

It’s hard for me to grasp what this is about. Description sounds like de-duplication but it adds a lot of code.

The second commit is an example of migrating an app to the new api or is it more than this? It feels like it’s mixed with implementing the API.

It’s an issue that NodeAttributeRegistry is used in OCA while defined in OC, it needs a public API or it should be moved to apps/dav if it’s only used there, not clear to me.

It's clearer when you read the RFC linked with it :)

The serializer and the DAV plugin both preload through the registry,
which only passes the nodes a provider has not preloaded yet for the
same context and attributes. Providers no longer need to skip known
nodes or preload lazily from getAttributes().

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: John Molakvoæ <14975046+skjnldsv@users.noreply.github.com>
@skjnldsv

Copy link
Copy Markdown
Member Author

It’s hard for me to grasp what this is about. Description sounds like de-duplication but it adds a lot of code.

The second commit is an example of migrating an app to the new api or is it more than this? It feels like it’s mixed with implementing the API.

Updated the main description. That way it's a bit clearer without reading the rfc 👍

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RFC] One file representation for DAV and PHP: node attribute providers

3 participants