Issue #3630926: Preserve case-sensitive managed-file URL paths
Closes #3630926
Issue: https://www.drupal.org/project/entity_usage/issues/3630926
Fix
Preserve the case-sensitive path through the shared URL-to-entity resolver. Normalize only hostname matching (including Unicode/IDN hostname case), and compare schemes case-insensitively. Keep configured/discovered site and public-wrapper base paths unchanged. Reuse the same domain conversion in the legacy update hook.
The public-file subscriber now derives the managed URI from the parsed path, without query/fragment suffixes, and uses rawurldecode() so plus signs are not mistaken for spaces. Absolute and protocol-relative CDN URLs retain their path case. File entity queries remain exact: files differing only by filename case resolve to distinct IDs.
No new dependencies, configuration workaround, content rewriting, or file renaming. This does not change Media File Delete's duplicate-counting logic.
Regression evidence
- Existing kernel file-tracking test extended with real file entities, real URI queries, and saved plain HTML field tracking.
- Cases: lowercase and mixed-case filenames/directories; case-distinct files; absolute, root-relative and relative paths; uppercase and Unicode hostname case; encoded spaces and encoded/literal plus signs; query/fragment suffixes; external-host and wrong-case directory rejection; mixed-case non-local public-wrapper/CDN base paths (absolute and protocol-relative).
- SiteDomains unit coverage and legacy domain conversion kernel coverage included. Previous unit expectations for whole-path lowercasing updated to the new path-preserving contract.
- Without the production fix,
EntityUsageTrackFileTest::testCaseSensitiveFileUrlsfails onMixedDirectory/MixedCase.pdf: NULL managed-file resolution. With the fix, the focused kernel/URL/domain/public-file checks pass: 56 tests, 260 assertions on Drupal 11.4.4 / PHP 8.4 / PHPUnit 11.5. - Local real bulk-media-delete check: saved draft's plain mixed-case PDF link recorded as node/body
html_link; linked file retained (entity/disk present, HTTP 200); unreferenced lowercase control deleted (entity/disk absent, HTTP 404). No media or core file-usage records remained to mask retention. Disposable fixtures cleaned up. - Clean Composer reinstall on locked Entity Usage 5.0.1 verified separately.
CI results still require review. Recreate existing Entity Usage data after deploying to each environment; avoid file deletion during rebuilds. The patch only corrects reference recognition and does not establish that every deletion workflow is safe.
AI-assisted investigation/coding; results verified by executable regression and focused local integration checks. Public report and tests use synthetic examples only.