Controller Customization
You can customize the upload behavior by extending the default controller and implementing the StorageMultipartUploadControllerContract.
Custom Controller Example
use MrEduar\S3M\Contracts\ StorageMultipartUploadControllerContract ;
use MrEduar\S3M\Http\Controllers\ S3MultipartController ;
use Illuminate\Http\ JsonResponse ;
use MrEduar\S3M\Http\Requests\ CreateMultipartUploadRequest ;
class CustomS3MultipartController extends S3MultipartController implements StorageMultipartUploadControllerContract
{
/**
* Override the getKey method to customize folder structure
*/
protected function getKey ( string $uuid , string $folder ) : string
{
$userId = auth () -> id ();
$date = date ( 'Y/m/d' );
return "uploads/{ $userId }/{ $date }/{ $folder }/{ $uuid }" ;
}
/**
* Override default visibility
*/
protected function defaultVisibility () : string
{
return 'public-read' ;
}
/**
* Add custom logic to createMultipartUpload
*/
public function createMultipartUpload ( CreateMultipartUploadRequest $request ) : JsonResponse
{
// Add custom validation or logic
if ( ! auth () -> user () -> canUploadFiles ()) {
return response () -> json ([ 'error' => 'Unauthorized' ], 403 );
}
return parent :: createMultipartUpload ( $request );
}
}
Register Custom Controller
Update your route service provider or routes file:
use App\Http\Controllers\ CustomS3MultipartController ;
Route :: post ( '/s3m/create-multipart-upload' , [ CustomS3MultipartController :: class , 'createMultipartUpload' ]);
Route :: post ( '/s3m/create-sign-part' , [ CustomS3MultipartController :: class , 'signPartUpload' ]);
Route :: post ( '/s3m/complete-multipart-upload' , [ CustomS3MultipartController :: class , 'completeMultipartUpload' ]);
Middleware Configuration
Customize the middleware applied to multipart upload routes in config/s3m.php:
'middleware' => [
'web' ,
'auth' ,
'throttle:60,1' ,
],
Available Middleware Options
web - Standard web middleware group
auth - Require authentication
auth:sanctum - API token authentication
throttle:60,1 - Rate limiting (60 requests per minute)
Custom middleware for additional validation
Visibility Settings
Configuration
Control whether users can change file visibility in config/s3m.php:
/**
* Indicates whether the visibility of the uploaded file can be modified.
* The default visibility setting is private.
*/
'allow_change_visibility' => true ,
Default Visibility
The default visibility is private. Override the defaultVisibility() method in your custom controller:
protected function defaultVisibility () : string
{
return 'private' ; // Options: 'private', 'public-read', 'public-read-write'
}
The defaultVisibility() method in S3MultipartController.php:164-167 returns the ACL for uploaded files.
Client-Side Visibility
Pass visibility option when creating an upload:
const uploader = new S3M ( file , {
data: {
visibility: 'public-read' ,
},
});
Folder Structure Customization
Configuration
Control folder permissions in config/s3m.php:
/**
* Indicates whether the folder of the uploaded file can be changed.
* By default, files are stored in the /tmp/ directory at the root of the bucket,
* following the format /tmp/{filename}, where {filename} is the UUID generated for the upload.
*/
'allow_change_folder' => false ,
Custom Folder Structure
Controller Override
User-Based Folders
Environment-Based Folders
protected function getKey ( string $uuid , string $folder ) : string
{
// Organize by year/month/day
$datePath = date ( 'Y/m/d' );
return "uploads/{ $datePath }/{ $folder }/{ $uuid }" ;
}
The getKey() method is called in S3MultipartController.php:156-159 to generate the S3 object key.
Client-Side Folder Selection
const uploader = new S3M ( file , {
data: {
folder: 'documents' , // Custom folder name
},
});
Bucket Configuration
Allow Bucket Changes
Configure in config/s3m.php:
/**
* Indicates whether the bucket of the uploaded file can be changed.
* The default bucket is the one configured below.
*/
'allow_change_bucket' => true ,
Default Bucket
's3' => [
'bucket' => env ( 'AWS_BUCKET' ),
// ... other S3 settings
],
Client-Side Bucket Selection
const uploader = new S3M ( file , {
data: {
bucket: 'my-custom-bucket' ,
},
});
Ensure your AWS credentials have permissions for the specified bucket when allowing bucket changes.
Content Type Customization
Server-Side Default
The default content type is application/octet-stream (see S3MultipartController.php:137).
Custom Content Type
protected function createCommand ( Request $request , S3Client $client , string $bucket ) : CommandInterface
{
$contentType = $request -> input ( 'content_type' ) ?: $this -> getContentType ( $request );
return $client -> getCommand ( 'UploadPart' , [
// ...
'ContentType' => $contentType ,
]);
}
protected function getContentType ( Request $request ) : string
{
// Custom logic to determine content type
$extension = pathinfo ( $request -> input ( 'filename' ), PATHINFO_EXTENSION );
return match ( $extension ) {
'pdf' => 'application/pdf' ,
'jpg' , 'jpeg' => 'image/jpeg' ,
'png' => 'image/png' ,
default => 'application/octet-stream' ,
};
}
Presigned URL Expiration
The default expiration for presigned URLs is 5 minutes (see S3MultipartController.php:76).
Custom Expiration
protected function getPresignedUrlExpiration () : int
{
return 15 ; // 15 minutes
}
public function signPartUpload ( SignPartRequest $request ) : JsonResponse
{
// ...
$signedRequest = $client -> createPresignedRequest (
$this -> createCommand ( $request , $client , $bucket ),
sprintf ( '+%s minutes' , $this -> getPresignedUrlExpiration ())
);
// ...
}
Shorter expiration times are more secure but may cause issues with slow connections. Balance security with usability.