This way, there is no need to include the `formError` template manually anymore.
See #2509
});
</script>
+{if $form->hasValidationErrors() && $form->showsErrorMessage()}
+ <p class="error" role="alert">{@$form->getErrorMessage()}</p>
+{/if}
+
{if $form->isAjax()}
<section id="{@$form->getId()}"{*
*}{if !$form->getClasses()|empty} class="{implode from=$form->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{*
{/foreach}
</div>
{/if}
-
- {@SECURITY_TOKEN_INPUT_TAG}
+
{if $form->isAjax()}
</section>
{else}
+ {@SECURITY_TOKEN_INPUT_TAG}
</form>
{/if}
});
</script>
+{if $form->hasValidationErrors() && $form->showsErrorMessage()}
+ <p class="error" role="alert">{@$form->getErrorMessage()}</p>
+{/if}
+
{if $form->isAjax()}
<section id="{@$form->getId()}"{*
*}{if !$form->getClasses()|empty} class="{implode from=$form->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{*
{/foreach}
</div>
{/if}
-
- {@SECURITY_TOKEN_INPUT_TAG}
+
{if $form->isAjax()}
</section>
{else}
+ {@SECURITY_TOKEN_INPUT_TAG}
</form>
{/if}
<p class="warning">{lang}wcf.acp.devtools.project.edit.warning{/lang}</p>
{/if}
-{include file='formError'}
-
{if $success|isset}
<p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
{/if}
</nav>
</header>
-{include file='formError'}
-
{if $success|isset}
<p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
{/if}
</nav>
</header>
-{include file='formError'}
-
{if $success|isset}
<p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
{/if}
</nav>
</header>
-{include file='formError'}
-
{if $success|isset}
<p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
{/if}
// call validate event
EventHandler::getInstance()->fireAction($this, 'validate');
+ $this->validateSecurityToken();
+ }
+
+ /**
+ * Validates the form security token.
+ *
+ * @throws UserInputException if the security token is invalid
+ * @since 5.2
+ */
+ protected function validateSecurityToken() {
if (!isset($_POST['t']) || !WCF::getSession()->checkSecurityToken($_POST['t'])) {
throw new UserInputException('__securityToken');
}
throw new UserInputException($this->form->getPrefixedId());
}
}
+
+ /**
+ * @inheritDoc
+ */
+ protected function validateSecurityToken() {
+ // does nothing, is handled by `IFormDocument` object
+ }
}
use TFormNode;
use TFormParentNode {
TFormParentNode::cleanup insteadof TFormNode;
- readValues as protected defaultReadValues;
+ hasValidationErrors as protected traitHasValidationErrors;
+ readValues as protected traitReadValues;
+ validate as protected traitValidate;
}
/**
*/
protected $enctype = '';
+ /**
+ * global form error message
+ * @var null|string
+ */
+ protected $errorMessage;
+
/**
* is `true` if form document has already been built and is `false` otherwise
* @var bool
*/
protected $isBuilt = false;
+ /**
+ * is `true` if form document is in invalid due to external factors and is `false` otherwise
+ * @var boolean
+ */
+ protected $invalid = false;
+
/**
* form mode (see `self::FORM_MODE_*` constants)
* @var null|string
*/
protected $requestData;
+ /**
+ * TODO
+ * @var boolean
+ */
+ protected $showErrorMessage = true;
+
/**
* Cleans up the form document before the form document object is destroyed.
*/
FormButton::create('submitButton')
->label('wcf.global.button.submit')
->accessKey('s')
+ ->submit(!$this->isAjax())
->addClass('buttonPrimary')
);
}
+ /**
+ * @inheritDoc
+ */
+ public function errorMessage($languageItem = null, array $variables = []) {
+ if ($languageItem === null) {
+ if (!empty($variables)) {
+ throw new \InvalidArgumentException("Cannot use variables when unsetting error element of form '{$this->getId()}'");
+ }
+
+ $this->errorMessage = null;
+ }
+ else {
+ if (!is_string($languageItem)) {
+ throw new \InvalidArgumentException("Given error message language item is no string, " . gettype($languageItem) . " given.");
+ }
+
+ $this->errorMessage = WCF::getLanguage()->getDynamicVariable($languageItem, $variables);
+ }
+
+ return $this;
+ }
+
/**
* @inheritDoc
*/
return $this->enctype;
}
+ /**
+ * @inheritDoc
+ */
+ public function getErrorMessage() {
+ if ($this->errorMessage === null) {
+ $this->errorMessage = WCF::getLanguage()->getDynamicVariable('wcf.global.form.error');
+ }
+
+ return $this->errorMessage;
+ }
+
/**
* @inheritDoc
*/
return $this->addDefaultButton;
}
+ /**
+ * @inheritDoc
+ */
+ public function hasValidationErrors() {
+ return $this->isInvalid() || $this->traitHasValidationErrors();
+ }
+
/**
* @inheritDoc
*/
return !empty($requestData);
}
+ /**
+ * @inheritDoc
+ */
+ public function invalid($invalid = true) {
+ $this->invalid = $invalid;
+
+ return $this;
+ }
+
/**
* @inheritDoc
*/
return $this->ajax;
}
+ /**
+ * @inheritDoc
+ */
+ public function isInvalid() {
+ return $this->invalid;
+ }
+
/**
* @inheritDoc
*/
$this->requestData = $_POST;
}
- return $this->defaultReadValues();
+ return $this->traitReadValues();
}
/**
return $this;
}
+
+ /**
+ * @inheritDoc
+ */
+ public function showErrorMessage($showErrorMessage = true) {
+ $this->showErrorMessage = $showErrorMessage;
+
+ return $this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function showsErrorMessage() {
+ return $this->showErrorMessage;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function validate() {
+ // check security token
+ if (!isset($_POST['t']) || !WCF::getSession()->checkSecurityToken($_POST['t'])) {
+ $this->invalid();
+
+ $this->errorMessage('wcf.global.form.error.securityToken');
+ }
+ else {
+ $this->traitValidate();
+ }
+ }
}
* @throws \BadMethodCallException if this document has already been built
*/
public function build();
+
+ /**
+ * Sets the error message of this form using the given language item and returns this
+ * document. If `null` is passed, the error message is unset.
+ *
+ * Unsetting the current error message causes `IFormDocument::getErrorMessage()` to
+ * return the default error message.
+ *
+ * @param null|string $languageItem language item containing the error message or `null` to unset error message
+ * @param array $variables additional variables used when resolving the language item
+ *
+ * @return static this document
+ *
+ * @throws \InvalidArgumentException if the given form mode is invalid
+ */
+ public function errorMessage($languageItem = null, array $variables = []);
/**
* Sets the form mode (see `self::FORM_MODE_*` constants).
*/
public function getEnctype();
+ /**
+ * Returns the error message for the whole form.
+ *
+ * By default, `wcf.global.form.error` in the active user's language is returned.
+ * This method always returns the error message! To check, if the error message should
+ * be displayed, use `IParentFormNode::hasValidationErrors()` and
+ * `IFormDocument::showsErrorMessage()`.
+ *
+ * @return string
+ */
+ public function getErrorMessage();
+
/**
* Returns the form mode (see `self::FORM_MODE_*` constants).
*
* If no request data is set, `$_POST` will be set as the request data.
*
* @param null|string $index array index of the returned data
- * @return bool `tu
+ * @return bool
*/
public function hasRequestData($index = null);
*/
public function isAjax();
+ /**
+ * Returns `true` if the form document is in invalid due to external factors and is `false`
+ * otherwise.
+ *
+ * By default, the form document is not invalid.
+ *
+ * @return boolean
+ */
+ public function isInvalid();
+
+ /**
+ * Sets if the form document is in invalid due to external factors.
+ *
+ * @param boolean $invalid
+ * @return static this document
+ */
+ public function invalid($invalid = true);
+
/**
* Loads the field values from the given object and returns this document.
*
* Sets the request data of the form's fields.
*
* @param array $requestData request data of the form's fields
- * @return static this field
+ * @return static this document
*
* @throws \BadMethodCallException if request data has already been set
*/
public function requestData(array $requestData);
+
+ /**
+ * Sets if the global form error message should be shown if the form has validation errors.
+ *
+ * @param boolean $showErrorMessage
+ * @return static this document
+ */
+ public function showErrorMessage($showErrorMessage = true);
+
+ /**
+ * Returns `true` if the global form error message should be shown if the form has validation
+ * errors.
+ *
+ * By default, the global form error message is shown.
+ *
+ * @return boolean
+ */
+ public function showsErrorMessage();
}