Skip to content

[access] refactor(files-widget): split FilesWidgetService listing, upload, delete and folder resolution into named steps - #1074

Closed
rubenvdlinde wants to merge 2 commits into
developmentfrom
quality/i40-fileswidget-steps
Closed

rubenvdlinde wants to merge 2 commits into
developmentfrom
quality/i40-fileswidget-steps

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What changed

FilesWidgetService reads as named steps instead of thirteen branchy methods:

  • Listing. getContentsForPlacement resolves the folder, descends, checks it is readable and hands it to listVisibleItems (isListed, then sortItems, whose comparator comes from itemComparator instead of a branchy closure).
  • Folder resolution. resolveConfiguredFolder (public, unchanged signature) → configuredNode → resolveByFileId (firstFolder) / resolveByPath / homeWhenUnconfigured; extractFileId → positiveIntFromDigits; descendInto → nodeBelow.
  • Upload. uploadFiles (public, unchanged) checks the placement flag, resolves the folder and writableFolder, then storeUploads → storeUpload (screening) → writeUpload. Screening is rejectUpload → isGenuineUpload → size cap → rejectUploadType. resolveAvailableName → sanitiseUploadName → firstFreeNumberedName → numberedName. The destination folder and its MIME filter travel as one FilesWidgetUploadTarget.
  • Delete. deleteFile (public, unchanged) checks the placement flag, resolves the folder, then userNodeById, assertDeletableWithin and deleteNode; the containment walk is isDescendantOf → hasAncestorWithId → parentOf.
  • The two copies of the MIME pattern loop (matchesMimeFilter for nodes, mimeMatchesFilter for uploads) now share mimeMatchesFilter / mimeMatchesPattern.

Allowed and refused outcomes are unchanged, every check runs before the operation it guards and in the original order, and the exceptions and error codes are the same.

Characterisation tests

tests/Unit/Service/FilesWidgetAccessGoldenTest.php was committed first, against the old code, and passes before and after. It pins fileId / folderPath / home-folder resolution (every fileId shape, file-not-folder fallback, missing and unreadable folders, user-folder failure), every refused sub-path (traversal not even looked up, missing, not permitted, a file, unreadable) and the propagation of other lookup errors, the listing order for each sort and the MIME filter, paging and limit clamping, the upload refusals in order (placement flag before any lookup, read-only target) and every per-entry screening code with the collision-free names, and every delete outcome (flag before any lookup, missing id, lookup error, outside the root, unreadable parent, beyond the walk depth, not deletable, failing delete, direct and nested children, the root itself). The upload screening test registers its temp files as genuine uploads through a namespaced test seam for is_uploaded_file; every other path still goes to PHP. Mutation check: making the containment walk always succeed on the old code turned three delete goldens red; restored before committing.

What ran

  • vendor/bin/phpunit -c phpunit.xml --no-coverage tests/Unit: 2795 tests OK (13 skipped, as on development).
  • vendor/bin/phpcs and vendor/bin/phpstan analyse on the touched lib files: clean.

Figures (touched files lib/Service/FilesWidgetService.php, lib/Service/FilesWidgetUploadTarget.php)

before after
units over complexity 5 13 units, 311 lines 0
units over 15 lines of code 16 units, 385 lines 4 units, 84 lines (untouched methods)
units over 2 parameters 7 units, 178 lines 7 units, 86 lines
duplicated windows inside the service 6 0

App-wide: unit complexity 4.02 → 4.17, unit size 3.40 → 3.44, unit interfacing 3.14 → 3.17, duplication 4.54 → 4.55.

Maintainability floor: compare against development holds.

AI-assisted: prepared with Claude Code (claude-opus-5-5); reviewed by a maintainer before merge.


Generated by Claude Code

… uploads and deletes before the split

Assisted-by: ClaudeCode:claude-opus-5-5
…ete and folder resolution into named steps

Assisted-by: ClaudeCode:claude-opus-5-5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants