diff --git a/src/LiveComponent/composer.json b/src/LiveComponent/composer.json index 6b48567e415..08d674b3896 100644 --- a/src/LiveComponent/composer.json +++ b/src/LiveComponent/composer.json @@ -45,6 +45,7 @@ "symfony/expression-language": "^5.4|^6.0|^7.0|^8.0", "symfony/form": "^5.4|^6.0|^7.0|^8.0", "symfony/framework-bundle": "^5.4|^6.0|^7.0|^8.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0|^8.0", "symfony/options-resolver": "^5.4|^6.0|^7.0|^8.0", "symfony/phpunit-bridge": "^6.1|^7.0|^8.0", "symfony/security-bundle": "^5.4|^6.0|^7.0|^8.0", diff --git a/src/LiveComponent/src/ComponentWithFormTrait.php b/src/LiveComponent/src/ComponentWithFormTrait.php index fff01e0b73b..d491d36196c 100644 --- a/src/LiveComponent/src/ComponentWithFormTrait.php +++ b/src/LiveComponent/src/ComponentWithFormTrait.php @@ -13,8 +13,12 @@ use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView; use Symfony\Component\Form\ClearableErrorsInterface; +use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; +use Symfony\Component\Form\Util\FormUtil; +use Symfony\Component\Form\Util\ServerParams; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Symfony\Contracts\Translation\TranslatableInterface; use Symfony\UX\LiveComponent\Attribute\LiveProp; @@ -147,7 +151,7 @@ private function resetForm(bool $soft = false): void } } - private function submitForm(bool $validateAll = true): void + private function submitForm(bool $validateAll = true, ?Request $request = null): void { if (null !== $this->formView) { // Two scenarios can cause this: @@ -160,7 +164,50 @@ private function submitForm(bool $validateAll = true): void } $form = $this->getForm(); - $form->submit($this->formValues); + $method = $form->getConfig()->getMethod(); + + // For request methods that must not have a request body we fetch data + // from the query string. Otherwise we look for data in the request body. + if ('POST' === $method && $request instanceof Request) { + // Mark the form with an error if the uploaded size was too large + // This is done here and not in FormValidator because $_POST is + // empty when that error occurs. Hence the form is never submitted. + $serverParams = new ServerParams(); + if ($serverParams->hasPostMaxSizeBeenExceeded()) { + // Submit the form, but don't clear the default values + $form->submit(null, false); + + $form->addError(new FormError( + $form->getConfig()->getOption('upload_max_size_message')(), + null, + ['{{ max }}' => $serverParams->getNormalizedIniPostMaxSize()] + )); + + return; + } + + $name = $form->getName(); + + if ('' === $name) { + $params = $request->request->all(); + $files = $request->files->all(); + } elseif ($request->request->has($name) || $request->files->has($name)) { + $default = $form->getConfig()->getCompound() ? [] : null; + $params = $request->request->all()[$name] ?? $default; + $files = $request->files->get($name, $default); + } else { + // Don't submit the form if it is not present in the request + return; + } + + if (\is_array($params) && \is_array($files)) { + $data = FormUtil::mergeParamsAndFiles($params, $files); + } else { + $data = $params ?: $files; + } + } + + $form->submit($data ?? $this->formValues, $request); $this->shouldAutoSubmitForm = false; if ($validateAll) {