cloudinary-laravel
cloudinary-laravel copied to clipboard
fix prefix behavior
I noticed some odd behavior when using prefixes, so I threw this together. Happy to discuss. Thanks!
Summary
CloudinaryStorageAdapter: Normalize paths, prevent double prefixing, and infer resource type for getUrl/write
This PR improves CloudinaryStorageAdapter path handling and resource-type detection to produce correct public IDs and URLs across platforms, while avoiding double application of the configured prefix. It also adds comprehensive unit tests to guard against regressions.
Key Changes
- Path normalization and ID construction
- Normalize backslashes to forward slashes for all incoming paths.
- Build
public_idusingdirname/filenamewith forward slashes only, ensuring nested directories are preserved. - Strip leading
./or/when applying a prefix to avoidprefix/./fileorprefix//fileartifacts. - Prevent double prefixing when a path is already prefixed.
- Resource type inference
- Detect MIME type from the normalized path and choose
resource_typevia:image/*→imagevideo/*→video- else →
raw
- Detect MIME type from the normalized path and choose
- getUrl correctness
getUrlnow resolves the correctpublic_idand inferredresource_typebefore querying Admin API, ensuring the returned secure URL matches the resource.
- Prefix application helper
applyPrefixToPathnow short-circuits if the incoming path already begins with the configured prefix, preventing duplication in list/delete directory operations.
- Internal/API ergonomics
- Use PHP’s
str_starts_withand a smallmatch(true)to improve clarity.
- Use PHP’s
Files Changed
src/CloudinaryStorageAdapter.php- Refactor
prepareResourceto normalize paths, construct IDs consistently, apply prefix safely, and inferresource_typefrom MIME type. - Guard
applyPrefixToPathagainst double prefixing.
- Refactor
tests/Unit/CloudinaryStorageAdapterTest.php- Add tests for:
- Image path with backslashes → normalized
public_idandimageresource type. - Video path →
videoresource type. - Non-image/video path →
rawresource type. - Prefix behavior with leading
./and/stripping. - Nested backslash paths under a prefix.
getUrlbehavior for images and videos.getUrlwith prefixed adapter:- Applies prefix when needed.
- Does not double-apply when path already includes prefix.
- Handles leading slash without double prefix.
- Normalizes backslashes in incoming path.
- Image path with backslashes → normalized
- Add tests for:
Why
- Fixes incorrect
public_idgeneration on Windows-like inputs (backslashes), preventing broken uploads/URL lookups. - Prevents
Fixtures/Fixtures/...orFixtures//...issues when users pass already-prefixed paths or paths with leading separators. - Ensures correct
resource_typeis used for Admin/Upload API calls, avoiding 400s due to mismatched types.
Behavior Examples
- Incoming:
dir\nested\picture.jpg- Before: Could become malformed
public_idwith backslashes and wrongresource_type. - After:
public_id=dir/nested/picture,resource_type=image.
- Before: Could become malformed
- Incoming with prefix
Fixtures:/file.jpgor./file.jpg- After:
public_id=Fixtures/file, no double prefixing.
- After:
getUrl('media/clip.mp4')- After: Queries
asset('media/clip', ['resource_type' => 'video'])and returnssecure_url.
- After: Queries
Tests
- Expanded unit tests cover the above scenarios and serve as regression tests for path normalization and prefix logic.
Backwards Compatibility
- Behavior changes are corrective and align with expected usage:
- More accurate
public_idandresource_typedetection. - Safer prefix handling. Existing code that relied on prior incorrect behavior may see corrected IDs/URLs.
- More accurate
- Requires PHP with
str_starts_with(PHP 8.0+).
Risks
- Edge cases in prefix comparison:
str_starts_with($trimmed, $this->prefix)assumes exact textual prefix; if users intentionally pass different-cased prefixes, behavior will not double-apply but may differ on case-sensitive expectations.
Rollout/Verification
- Run the added unit tests to verify behavior across common cases.
- Manually verify URLs for a few sample images and videos with and without prefixes.
Checklist
- [x] Path normalization across all entry points
- [x] No double prefixing in
getUrl,listContents,delete* - [x] Correct
resource_typeinference for image/video/raw - [x] Unit tests for regressions and new behavior