Goldenf's avatar

Serialization of 'Illuminate\\Http\\UploadedFile' is not allowed"

I am trying to email a user when a request is submitted. If a request is submitted without uploading a file the email goes through. When a file is uploaded I get "Serialization of 'Illuminate\Http\UploadedFile' is not allowed"

public function makeRequest($request, $template_id)

{

    DB::beginTransaction();

    try {
        $template = $this->template::findOrFail($template_id);

        // Create a new submission
        $submission = $this->answerSubmission::create([
            'request_management_id' => $template->id,
            'department_id' => Auth::user()->department,
            'user_id' => Auth::user()->id,
        ]);

        if ($template->template_type == null) {
            $rules = [
                'answers' => 'required|array',
                'answers.*.question_id' => 'required|exists:request_management_questions,id'
            ];

            foreach ($template->questions as $index => $question) {
                $rule = [];

                if ($question->required) {
                    $rule[] = 'required';
                } else {
                    $rule[] = 'nullable';
                }

                switch ($question->type) {
                    case 'file':
                        if (isset($question->file['maximum_no_of_files'])) {
                            $rule[] = 'max:' . $question->file['maximum_no_of_files'];
                        }
                        if (isset($question->file['file_size'])) {
                            $rule[] = 'max:' . ($question->file['file_size'] * 1024);
                        }
                        break;
                }

                $rules['answers.' . $index . '.answer'] = $rule;
            }

            $validatedData = $request->validate($rules);

            $processedAnswers = [];

            foreach ($validatedData['answers'] as $index => $answerData) {
                $questionId = $answerData['question_id'];
                $answerValue = $answerData['answer'];

                $question = $template->questions->where('id', $questionId)->first();
                if ($question->type == 'file' && $request->hasFile("answers.{$index}.answer")) {
                    $fileInputs = $request->file("answers.{$index}.answer");

                    $uploadedFileUrls = [];
                    foreach ($fileInputs as $fileInput) {
                        if ($fileInput && $fileInput->isValid()) {
                            $uploadedFileUrl = Cloudinary::upload($fileInput->getRealPath())->getSecurePath();
                            $uploadedFileUrls[] = $uploadedFileUrl;
                        } else {
                            $processedAnswers['errors'][] = "File upload error for question_id: {$questionId}.";
                        }
                    }

                    $processedAnswers[$questionId] = $uploadedFileUrls;
                } else {
                    $processedAnswers[$questionId] = $answerValue;
                }

                $this->saveAnswers($processedAnswers[$questionId], $template, $submission, $questionId);
            }
        }

        if ($template->template_type === 'expense-report') {
            $this->expenseReport($request, $submission, $template);
        }

        $emailSent = false;
        $authorizationLevels = $template->authorization_levels;
        for ($i = 1; $i <= $template->no_of_auth_levels; $i++) {
            $levelKey = 'level' . $i;
            $authorizer = isset($authorizationLevels[$levelKey]) ? $authorizationLevels[$levelKey] : null;

            $approverId = self::getAuthorizersId($authorizer);

            $this->requestApproval::create([
                'request_management_answer_submission_id' => $submission->id,
                'level' => $i,
                'status' => 'pending',
                'approver_id' => is_array($approverId) ? $approverId['user_id'] : $approverId
            ]);

            // Send email if approver is found and email has not been sent yet
            if (!$emailSent && $approverId) {
                $approverEmail = is_array($approverId) ? $this->user::find($approverId['approver_id'])->contactInformation->primary_email : $this->user::find($approverId)->contactInformation->primary_email;
                if ($approverEmail) {
                    Mail::to($approverEmail)->send(new ApproveRequestEmail($submission->id));
                    $emailSent = true;
                }
            }
        }

        // Send user email
        $userEmail = $this->user::find(Auth::user()->id)->contactInformation->primary_email;
        Mail::to($userEmail)->send(new UserRequestEmail($submission->id));

        DB::commit();
    } catch (\Exception $e) {
        DB::rollBack();
        // Handle the exception, log it or rethrow it
        throw $e;
    }
}
0 likes
8 replies
Goldenf's avatar

@jlrdw I tried the answer in that discussion, but I still got the same error. Error only pops up when sending a mail

JussiMannisto's avatar

@Goldenf If you're getting the same error, then you're still serializing the uploaded file somewhere. Post the code changes you made.

The error page (or log record) will show you a lot more than just a simple message. The stack trace below the error message will show you where exactly the error occurs.

Goldenf's avatar

public function makeRequest($request, $template_id) { DB::beginTransaction();

    try {
        $template = $this->template::findOrFail($template_id);

        // Create a new submission
        $submission = $this->answerSubmission::create([
            'request_management_id' => $template->id,
            'department_id' => Auth::user()->department,
            'user_id' => Auth::user()->id,
        ]);

        if ($template->template_type == null) {
            $rules = [
                'answers' => 'required|array',
                'answers.*.question_id' => 'required|exists:request_management_questions,id'
            ];

            foreach ($template->questions as $index => $question) {
                $rule = [];

                if ($question->required) {
                    $rule[] = 'required';
                } else {
                    $rule[] = 'nullable';
                }

                switch ($question->type) {
                    case 'file':
                        if (isset($question->file['maximum_no_of_files'])) {
                            $rule[] = 'max:' . $question->file['maximum_no_of_files'];
                        }
                        if (isset($question->file['file_size'])) {
                            $rule[] = 'max:' . ($question->file['file_size'] * 1024); // Convert MB to KB
                        }
                        break;
                }

                $rules['answers.' . $index . '.answer'] = $rule;
            }

            $validatedData = $request->validate($rules);

            $processedAnswers = [];
            $uploadedFileUrls = [];

            foreach ($validatedData['answers'] as $index => $answerData) {
                $questionId = $answerData['question_id'];
                $answerValue = $answerData['answer'];

                $question = $template->questions->where('id', $questionId)->first();

                if ($question->type == 'file' && $request->hasFile("answers.{$index}.answer")) {
                    $fileInputs = $request->file("answers.{$index}.answer");

                    foreach ($fileInputs as $fileInput) {
                        if ($fileInput && $fileInput->isValid()) {
                            $uploadedFilePath = $fileInput->store('public/uploads'); // Store locally
                            $uploadedFileUrl = Storage::url($uploadedFilePath);   // Get file URL
                            $uploadedFileUrls[] = $uploadedFileUrl;
                        } else {
                            $processedAnswers['errors'][] = "File upload error for question_id: {$questionId}.";
                        }
                    }

                    $processedAnswers[$questionId] = $uploadedFileUrls;
                } else {
                    $processedAnswers[$questionId] = $answerValue;
                }

                $this->saveAnswers($processedAnswers[$questionId], $template, $submission, $questionId);
            }
        }

        // Check if the template type is 'expense-report'
        if ($template->template_type === 'expense-report') {
            $this->expenseReport($request, $submission, $template);
        }

        $emailSent = false;
        $authorizationLevels = $template->authorization_levels;

        // Loop through authorization levels
        for ($i = 1; $i <= $template->no_of_auth_levels; $i++) {
            $levelKey = 'level' . $i;
            $authorizer = isset($authorizationLevels[$levelKey]) ? $authorizationLevels[$levelKey] : null;
            $approverId = self::getAuthorizersId($authorizer);

            $this->requestApproval::create([
                'request_management_answer_submission_id' => $submission->id,
                'level' => $i,
                'status' => 'pending',
                'approver_id' => is_array($approverId) ? $approverId['user_id'] : $approverId
            ]);

            // Send approver email if approver exists and email hasn't been sent yet
            if (!$emailSent && $approverId) {
                $approverEmail = is_array($approverId)
                    ? $this->user::find($approverId['approver_id'])->contactInformation->primary_email
                    : $this->user::find($approverId)->contactInformation->primary_email;

                if ($approverEmail) {
                    Mail::to($approverEmail)->send(new ApproveRequestEmail($submission->id));  // Use send() to avoid queuing
                    $emailSent = true;
                }
            }
        }

        // Send user notification email after approval setup
        $userEmail = $this->user::find(Auth::user()->id)->contactInformation->primary_email;
        Mail::to($userEmail)->send(new UserRequestEmail($submission->id));

        DB::commit();
    } catch (\Exception $e) {
        DB::rollBack();
        // Handle exception (log or rethrow)
        throw $e;
    }
}

here is the updated code.

"Serialization of 'Illuminate\Http\UploadedFile' is not allowed"

Goldenf's avatar

@JussiMannisto local.ERROR: Serialization of 'Illuminate\Http\UploadedFile' is not allowed {"exception":"[object] (Exception(code: 0): Serialization of 'Illuminate\Http\UploadedFile' is not allowed at C:\path\vendor\laravel\framework\src\Illuminate\Queue\Queue.php:158) [stacktrace] #0 C:\path\vendor\laravel\framework\src\Illuminate\Queue\Queue.php(158): serialize(Object(Smajo\MailLogger\Jobs\StoreMailEventToDatabase)) #1 C:\path\vendor\laravel\framework\src\Illuminate\Queue\Queue.php(127): Illuminate\Queue\Queue->createObjectPayload(Object(Smajo\MailLogger\Jobs\StoreMailEventToDatabase), 'default') #2 C:\path\vendor\laravel\framework\src\Illuminate\Queue\Queue.php(105): Illuminate\Queue\Queue->createPayloadArray(Object(Smajo\MailLogger\Jobs\StoreMailEventToDatabase), 'default', '')

Snapey's avatar

@Goldenf don't pass the uploaded image to the queued job. If it needs it, save it somewhere and pass the file path to your queued mail.

Goldenf's avatar

@Snapey Smajo\MailLogger package is saving the mail that's where the issue comes from.

Please or to participate in this conversation.