Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ Earlier releases (`v0.1.0-alpha.1` to `v0.1.7-alpha.1`) were experimental and do

---

## [v0.1.7-alpha.3] - 2024-06-13

### Added
- Storage root is now set to an absolute path by default for reliability (no .env needed)
- Improved Storage helper documentation and usage
- Enhanced symlink command for better cross-platform compatibility
- Updated documentation for new storage system and best practices

### Fixed
- Prevented duplicate/nested storage paths in uploads
- General codebase and documentation improvements

---

## [v0.1.7-alpha.2] - 2025-07-15

### Added
Expand Down
71 changes: 49 additions & 22 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,9 @@ This will run the production build process (minifies, strips dev code, precompil
- The old `build` command is now replaced by `bloom` for clarity and branding.
- Use this command before deploying your app to production.

## File Upload & Storage
## File Upload & Storage (v0.1.7+)

SproutPHP now includes a Storage helper for easy file uploads and URL generation, saving files in `public/uploads` for web accessibility.
SproutPHP now includes a robust Storage helper for file uploads and URL generation, saving files in `storage/app/public` for web accessibility via a symlink.

### Usage Example

Expand All @@ -516,44 +516,71 @@ use Core\Support\Storage;
// In your controller
if ($request->hasFile('avatar')) {
$path = Storage::put($request->file('avatar'), 'avatars');
$url = Storage::url($path); // /uploads/avatars/filename.jpg
$url = Storage::url($path); // /storage/avatars/filename.jpg
}
```

- Files are saved in `public/uploads/{subdir}`.
- URLs are generated as `/uploads/{subdir}/{filename}`.
- Files are saved in `storage/app/public/{subdir}`.
- URLs are generated as `/storage/{subdir}/{filename}`.
- The `public/storage` directory is a symlink (or junction on Windows) to `storage/app/public`.

---

## Modern Request File Access
### Storage Configuration

You can now access uploaded files in controllers using:
In `config/storage.php`:

```php
$request->file('avatar'); // Returns the file array or null
$request->hasFile('avatar'); // Returns true if a file was uploaded
'public' => [
'root' => env('STORAGE_PUBLIC_ROOT', 'storage/app/public'),
'url' => env('STORAGE_PUBLIC_LINK', '/storage'),
'visibility' => 'public',
],
```

Request data merges `$_GET`, `$_POST`, and JSON body for unified access.
### Creating the Symlink

---
To make uploaded files accessible via the web, create a symlink:

```bash
php sprout symlink:create
```
- This links `public/storage` to `storage/app/public`.
- On Windows, a directory junction is created for compatibility.

## File Validation: mimes & image
### Folder Structure

You can validate file uploads with new rules:
```
project-root/
├── public/
│ ├── assets/
│ ├── index.php
│ └── storage/ # symlink → ../storage/app/public
├── storage/
│ └── app/
│ └── public/
│ └── avatars/
│ └── uploadedfile.jpg
```

- `mimes:jpg,png,gif` — File must have one of the allowed extensions
- `image` — File must be a valid image (checked by MIME type)
### Accessing Uploaded Files

**Example:**
- After upload, files are accessible at `/storage/avatars/filename.jpg`.
- The `Storage::url($path)` helper generates the correct public URL.

### Example Controller Snippet

```php
$validator = new Validator($request->data, [
'avatar' => 'required|image|mimes:jpg,jpeg,png,gif'
]);
if ($request->hasFile('avatar')) {
$file = $request->file('avatar');
$path = Storage::put($file, 'avatars');
$avatarUrl = Storage::url($path); // Use in your views
}
```

---
### Notes
- Always use the `Storage` helper for uploads and URLs.
- The storage root is now absolute for reliability.
- No need to set or override the storage root in `.env` unless you have a custom setup.
- The CLI symlink command ensures public access to uploaded files.

## HTMX File Upload with

Expand Down
27 changes: 13 additions & 14 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
# SproutPHP v0.1.7-alpha.2 Release Notes
# SproutPHP v0.1.7-alpha.3 Release Notes

## 🎉 New Features & Improvements

- **File Upload & Storage:** New Storage helper for easy file uploads and URL generation, saving files in `public/uploads`.
- **Modern Request API:** Access uploaded files via `$request->file('avatar')` and `$request->hasFile('avatar')`.
- **Unified Input:** Request data now merges `$_GET`, `$_POST`, and JSON body for easier access.
- **Validation:** Added `mimes` and `image` rules for secure file validation.
- **HTMX File Upload:** File upload with progress bar using only HTMX, no custom JS required.
- **Error Handling:** Generic script to clear errors on focus for all fields.
- **Docs:** Updated with new usage examples and best practices.
- **Absolute Storage Path:** Storage root is now set to an absolute path by default for reliability; no need to set in .env for most use cases.
- **Updated Storage Helper:** Improved documentation and usage for file uploads and URL generation.
- **Symlink Command:** Enhanced for better cross-platform compatibility (Windows junctions, Linux/macOS symlinks).
- **Documentation:** DOCS.md updated to reflect new storage system, usage, and best practices.
- **Bugfix:** Prevented duplicate/nested storage paths in uploads.
- **General Improvements:** Codebase and documentation refinements.

## 🛠️ Upgrade Guide

- Use the new Storage helper and request methods for file uploads.
- Update your forms to use the new validation rules and error-clearing script.
- Use the new absolute storage root (no .env override needed).
- Run `php sprout symlink:create` to ensure correct symlink/junction for uploads.
- See DOCS.md for updated usage and examples.

## 📅 Release Date

2025-07-15
2024-06-13

## 📦 Framework Version

v0.1.7-alpha.2
v0.1.7-alpha.3

---

**Release Date**: 2025-07-15
**Framework Version**: v0.1.7-alpha.2
**Release Date**: 2024-06-13
**Framework Version**: v0.1.7-alpha.3
**PHP Version**: 8.1+
**Composer**: 2.0+