Fehlerbehandlung Formulare
Template
<label for="email"><f:translate key="tx_rsysworkbook_domain_model_frontenduser.email" /><span class="required">*</span></label>
<div class="formfields">
<f:form.textfield property="email" />
<f:render partial="FieldError" arguments="{ fieldName: 'email' }" />
</div>
Partial
Resources/Private/Partials/FormError.html
<f:form.errors>
<f:if condition="{error.propertyName}">
<f:for each="{error.errors}" as="errorDetail">
<f:if condition="{0:errorDetail.propertyName} == {0:'{fieldName}'}">
<f:for each="{errorDetail.errors}" as="errorDetailParts">
<div class="error">
<f:translate key="{errorDetail.propertyName}.{errorDetailParts.code}" />
<!-- {errorDetail.propertyName}.{errorDetailParts.code} {errorDetailParts.message}-->
</div>
</f:for>
</f:if>
</f:for>
</f:if>
</f:form.errors>
Texte
Resources/Private/Language/language.xlf
<trans-unit id="email.1301599608">
<source>Email ist bereits vergeben</source>
</trans-unit>
<trans-unit id="email.1221559976">
<source>Ungültige Emailadresse</source>
</trans-unit>
Model
Classes/Domain/Model/FrondendUser.php
/**
* email
*
* @var string
* @validate emailAddress(optional=true), Tx_Rsysworkbook_Domain_Validator_UniqueValidator(fieldname=email)
*/
protected $email = '';
Eigener Validator
Classes/Validator/UniqueValidator.php
<?php
/**
* A validator for unique email
*
* @scope singleton
*/
class Tx_Rsysworkbook_Domain_Validator_UniqueValidator extends Tx_Extbase_Validation_Validator_AbstractValidator {
/**
* Frontend user repository
*
* @var Tx_SfRegister_Domain_Repository_FrontendUserRepository
*/
protected $userRepository = NULL;
/**
* Inject frontend user repository
*
* @param Tx_Rsysworkbook_Domain_Repository_FrontendUserRepository $repository
* @return void
*/
public function injectUserRepository(Tx_Rsysworkbook_Domain_Repository_FrontendUserRepository $repository) {
$this->userRepository = $repository;
}
/**
* If the given passwords are valid
*
* @param string $value The value
* @return boolean
*/
public function isValid($value) {
$result = TRUE;
if ($this->userRepository->countByField($this->options['fieldname'], $value)) {
$this->addError($this->options['fieldname'] . ' is not unique', '1301599608');
$result = FALSE;
}
return $result;
}
}
?>
Repository
Classes/Domain/Repository/FrontendUserRepository.php
/**
* Count users in storagefolder which have a field that contains the value
*
* @param string $field
* @param string $value
* @return integer
*/
public function countByField($field, $value) {
$query = $this->createQuery();
$query->getQuerySettings()->setRespectEnableFields(FALSE);
return $query
->matching(
$query->logicalAnd(
$query->equals($field, $value),
$query->equals('deleted', 0)
)
)
->setLimit(1)
->execute()
->count();
}
Eigener Validator - Nachtrag
Der Validator oben zählt die Datensätze und wenn die Treffer > 0 sind gibt er falsch zurück, da nicht "unique". Soweit ja in Ordnung, aber wenn man den Datensatz später editiert, kommt derselbe Validator zum Einsatz. Jetzt gibt's das Problem, daß er den aktuell angezeigten Datensatz mitzählt und dann 1 Treffer zustande kommt und er meint, die Email wäre nicht "unique". Was aber falsch ist!
Eine elegante Lösung habe ich nicht gefunden, die Notlösung hier:
$result = TRUE;
$propertyName = $this->options['fieldname'];
// edit
$paramsEdit = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_rsysoffer_frontenduserprofile');
$paramsEdit = isset($paramsEdit['frontendUser']) ? $paramsEdit['frontendUser'] : '';
if(!empty($paramsEdit)) {
$uid = isset($paramsEdit['__identity']) ? $paramsEdit['__identity'] : '';
if ($this->frontendUserRepository->countByProperty($propertyName, $value, $uid)) {
$ret = $this->addError($this->options['fieldname'] . ' is not unique', '1301599608');
$result = FALSE;
}
}
// new
$paramsNew = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_rsysoffer_frontendusercreate');
$paramsNew = isset($paramsNew['newFrontendUser']) ? $paramsNew['newFrontendUser'] : '';
if(!empty($paramsNew)) {
if ($this->frontendUserRepository->countByProperty($propertyName, $value)) {
$ret = $this->addError($this->options['fieldname'] . ' is not unique', '1301599608');
$result = FALSE;
}
}
return $result;
Er sieht in den normalen GET Parametern nach, ob es ein neuer Datensatz ist, oder ein existierender editiert wird und zählt dann im letzteren Fall die eigne uid ($paramsEdit['__identity']) nicht mit.
Die Query sieht so aus (mit der Möglichkeit die eigene uid auszuschliessen):
public function countByProperty($property, $value, $uid = 0) {
$query = $this->createQuery();
$constraints = array();
$constraints[] = $query->equals('isParent', 0);
$constraints[] = $query->equals($property, $value);
if( $uid > 0) {
$constraints[] = $query->logicalNot($query->equals('uid', $uid));
}
$query->matching($query->logicalAnd($constraints));
return $query->execute()->count();
}
TYPO3 V11
Hier der Validator in aktueller Version
<?php
namespace RSYS\RsystemplateBootstrap\Domain\Validator;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* A validator for unique email
*
* @scope singleton
*/
class UniqueValidator extends \TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator {
/**
* @var array
*/
protected $supportedOptions = array(
'fieldname' => array(NULL, 'The validator type to use for the unique elements', 'string'),
);
/**
* userRepository
*
* @var \RSYS\RsystemplateBootstrap\Domain\Repository\UserRepository
* @TYPO3\CMS\Extbase\Annotation\Inject
*/
protected $userRepository = null;
/**
* Constructor
*/
public function __construct(
$params
)
{
$this->options = $params;
$this->userRepository = GeneralUtility::makeInstance(\RSYS\RsystemplateBootstrap\Domain\Repository\UserRepository::class);
}
/**
* If the given email is unique
*
* @param string $value The value
* @return boolean
*/
public function isValid($value) {
$result = TRUE;
$propertyName = $this->options['fieldname'];
// edit
$paramsEdit = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_rsystemplatebootstrap_user');
$paramsEdit = isset($paramsEdit['user']) ? $paramsEdit['user'] : '';
if(!empty($paramsEdit)) {
$uid = isset($paramsEdit['__identity']) ? $paramsEdit['__identity'] : '';
if ($this->userRepository->countByProperty($propertyName, $value, $uid)) {
$ret = $this->addError($this->options['fieldname'] . ' is not unique' , '1301599608');
$result = FALSE;
}
}
// new
$paramsNew = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_rsystemplatebootstrap_user');
$paramsNew = isset($paramsNew['newUser']) ? $paramsNew['newUser'] : '';
if(!empty($paramsNew)) {
if ($this->userRepository->countByProperty($propertyName, $value)) {
$ret = $this->addError($this->options['fieldname'] . ' is not unique', '1301599608');
$result = FALSE;
}
}
// print_r($ret);
return $result;
}
}
?>