action; } /** * Set the Form submission URL * * @param string $action * * @return $this */ public function setAction($action) { $this->action = $action; return $this; } /** * Get the HTTP method to submit the form with * * @return string */ public function getMethod() { return $this->method; } /** * Set the HTTP method to submit the form with * * @param string $method * * @return $this */ public function setMethod($method) { $this->method = strtoupper($method); return $this; } /** * Get whether the form has a primary submit button * * @return bool */ public function hasSubmitButton() { return $this->submitButton !== null; } /** * Get the primary submit button * * @return FormSubmitElement|null */ public function getSubmitButton() { return $this->submitButton; } /** * Set the primary submit button * * @param FormSubmitElement $element * * @return $this */ public function setSubmitButton(FormSubmitElement $element) { $this->submitButton = $element; return $this; } /** * Get the submit element used to send the form * * @return FormSubmitElement|null */ public function getPressedSubmitElement() { foreach ($this->submitElements as $submitElement) { if ($submitElement->hasBeenPressed()) { return $submitElement; } } return null; } /** * @return ServerRequestInterface|null */ public function getRequest() { return $this->request; } public function setRequest($request) { $this->request = $request; $this->emit(Form::ON_REQUEST, [$request]); return $this; } /** * Get the url to redirect to on success * * @return string */ public function getRedirectUrl() { return $this->redirectUrl; } /** * Set the url to redirect to on success * * @param string $url * * @return $this */ public function setRedirectUrl($url) { $this->redirectUrl = $url; return $this; } /** * @param ServerRequestInterface $request * @return $this */ public function handleRequest(ServerRequestInterface $request) { $this->setRequest($request); if (! $this->hasBeenSent()) { // Always assemble $this->ensureAssembled(); return $this; } switch ($request->getMethod()) { case 'POST': $params = $request->getParsedBody(); break; case 'GET': parse_str($request->getUri()->getQuery(), $params); break; default: $params = []; } $this->populate($params); // Assemble after populate in order to conditionally provide form elements $this->ensureAssembled(); if ($this->hasBeenSubmitted()) { if ($this->isValid()) { try { $this->emit(Form::ON_SENT, [$this]); $this->onSuccess(); $this->emitOnce(Form::ON_SUCCESS, [$this]); } catch (Exception $e) { $this->addMessage($e); $this->onError(); $this->emit(Form::ON_ERROR, [$e, $this]); } } else { $this->onError(); } } else { $this->validatePartial(); $this->emit(Form::ON_SENT, [$this]); } return $this; } /** * Get whether the form has been sent * * A form is considered sent if the request's method equals the form's method. * * @return bool */ public function hasBeenSent() { if ($this->request === null) { return false; } return $this->request->getMethod() === $this->getMethod(); } /** * Get whether the form has been submitted * * A form is submitted when it has been sent and when the primary submit button, if set, has been pressed. * This method calls {@link hasBeenSent()} in order to detect whether the form has been sent. * * @return bool */ public function hasBeenSubmitted() { if (! $this->hasBeenSent()) { return false; } if ($this->hasSubmitButton()) { return $this->getSubmitButton()->hasBeenPressed(); } return true; } /** * Get whether the form is valid * * {@link validate()} is called automatically if the form has not been validated before. * * @return bool */ public function isValid() { if ($this->isValid === null) { $this->validate(); $this->emit(self::ON_VALIDATE, [$this]); } return $this->isValid; } /** * Validate all elements * * @return $this */ public function validate() { $valid = true; foreach ($this->elements as $element) { if ($element->isRequired() && ! $element->hasValue()) { $element->addMessage('This field is required'); $valid = false; continue; } if (! $element->isValid()) { $valid = false; } } $this->isValid = $valid; return $this; } /** * Validate all elements that have a value * * @return $this */ public function validatePartial() { foreach ($this->getElements() as $element) { $element->validate(); } return $this; } public function remove(ValidHtml $elementOrHtml) { if ($this->submitButton === $elementOrHtml) { $this->submitButton = null; } $this->removeElement($elementOrHtml); } protected function onError() { $errors = Html::tag('ul', ['class' => 'errors']); foreach ($this->getMessages() as $message) { if ($message instanceof Exception) { $message = $message->getMessage(); } $errors->addHtml(Html::tag('li', $message)); } if (! $errors->isEmpty()) { $this->prependHtml($errors); } } protected function onSuccess() { // $this->redirectOnSuccess(); } protected function onElementRegistered(FormElement $element) { if ($element instanceof FormSubmitElement) { $this->submitElements[$element->getName()] = $element; if (! $this->hasSubmitButton()) { $this->setSubmitButton($element); } } $element->onRegistered($this); } protected function registerAttributeCallbacks(Attributes $attributes) { $attributes ->registerAttributeCallback('action', [$this, 'getAction'], [$this, 'setAction']) ->registerAttributeCallback('method', [$this, 'getMethod'], [$this, 'setMethod']); } }