I am converting base64 encoded string to UploadedFile for those fields ending with File.
Middleware
class Base64ToUploadedFileMiddleware
{
public function handle(Request $request, Closure $next)
{
$inputs = $request->request->all();
foreach($inputs as $fieldName => $fieldValue) {
if(str_ends_with($fieldName, 'File') && $fieldValue != null) {
$fileData = base64_decode(Arr::last(explode(',', $fieldValue)));
$tempFile = tmpfile();
$tempFilePath = stream_get_meta_data($tempFile)['uri'];
file_put_contents($tempFilePath, $fileData);
$tempFileObject = new File($tempFilePath);
$file = new UploadedFile(
$tempFileObject->getPathname(),
$tempFileObject->getFilename(),
$tempFileObject->getMimeType()
);
app()->terminating(function () use ($tempFile) {
fclose($tempFile);
});
$request->request->remove($fieldName);
$request->files->set($fieldName, $file);
}
}
return $next($request);
}
}
FormRequest
public function rules()
{
$alignments = ['LEFT', 'CENTER', 'RIGHT'];
$updateId = request('id', null);
$uniqueRule = 'unique:documents,header';
if($updateId)
$uniqueRule .= ',' . $updateId . ',id,created_by,' . auth()->user()->id;
return [
'headerText' => [ 'required', 'max:255', $uniqueRule ],
'headerTextAlignment' => [ 'required', 'in:' . implode(',', $alignments) ],
'headerLogoFile' => [ 'nullable', 'file', 'mimes:jpeg,jpg,png', 'size:2000'],
'headerLogoAlignment' => [ 'nullable', 'in:' . implode(',', $alignments) ],
'content' => [ 'required', 'not_regex:/\<script\>[^<]*\<\/script\>/i' ],
'pdfFile' => [ 'required', 'file', 'mimes:pdf', 'size:100000' ]
];
}
When I try to upload the converted file inside middleware, it is uploaded successfully, but when validation rules complete processing - it shows errors for files like the following -
JSON Response
{
"message": "The given data was invalid.",
"errors": {
"headerLogoFile": [
"The header logo file failed to upload."
]
}
}
The nullable
& file
rules aren't compatible with each other (if the field is missing from the request, the file
rule will trigger regardless of whether nullable
is in the ruleset).
I think this is because the under the hood, those fields will arrive in the $_FILES
superglobal instead of the $_POST
. There is an example of handling this by validating any file uploads separately to the standard fields in the store
method here: https://github.com/musimana/bassform/blob/main/app/Http/Controllers/Public/PageController.php (I left it in the controller since it's just an example method, but it could easily be moved to a FormRequest
).
If anyone knows a more 'Laravelly' way to do it then I'd love to know!
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community