Skip to content

Commit

Permalink
refactored list entry validation callbacks as custom validation
Browse files Browse the repository at this point in the history
constraint
  • Loading branch information
Guite committed Mar 29, 2017
1 parent 15e7037 commit 0c9f5c5
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 64 deletions.
Expand Up @@ -53,6 +53,9 @@ class ServiceDefinitions {
generateServiceFile(fsa, 'linkContainer', linkContainer)
generateServiceFile(fsa, 'entityFactory', entityFactory)
generateServiceFile(fsa, 'eventSubscriber', eventSubscriber)
if (hasListFields) {
generateServiceFile(fsa, 'validators', validators)
}
if (hasEditActions) {
generateServiceFile(fsa, 'formFields', formFields)
}
Expand All @@ -67,6 +70,9 @@ class ServiceDefinitions {
- { resource: 'linkContainer.yml' }
- { resource: 'entityFactory.yml' }
- { resource: 'eventSubscriber.yml' }
«IF hasListFields»
«' '»- { resource: 'validators.yml' }
«ENDIF»
«IF hasEditActions»
«' '»- { resource: 'formFields.yml' }
«ENDIF»
Expand Down Expand Up @@ -188,6 +194,22 @@ class ServiceDefinitions {
listeners
}
def private validators(Application it) '''
services:
«validatorServices»
'''
def private validatorServices(Application it) '''
# Custom validators
«modPrefix».validator.list_entry.validator:
class: «appNamespace»\Validator\Constraints\ListEntryValidator
arguments:
- "@translator.default"
- "@«modPrefix».listentries_helper"
tags:
- { name: validator.constraint_validator, alias: «vendor.formatForDB».«name.formatForDB».listentry.validator }
'''
def private formFields(Application it) '''
services:
«formFieldsHelper»
Expand Down
Expand Up @@ -9,6 +9,7 @@ import de.guite.modulestudio.metamodel.EntityIndexItem
import de.guite.modulestudio.metamodel.InheritanceRelationship
import de.guite.modulestudio.metamodel.MappedSuperClass
import org.eclipse.xtext.generator.IFileSystemAccess
import org.zikula.modulestudio.generator.cartridges.zclassic.models.business.ListEntryValidator
import org.zikula.modulestudio.generator.cartridges.zclassic.models.business.ValidationConstraints
import org.zikula.modulestudio.generator.cartridges.zclassic.models.entity.Association
import org.zikula.modulestudio.generator.cartridges.zclassic.models.entity.EntityConstructor
Expand Down Expand Up @@ -71,6 +72,9 @@ class Entities {
new StandardFieldsTrait().generate(it, fsa, false)
}
}
if (hasListFields) {
new ListEntryValidator().generate(it, fsa)
}

for (entity : getAllEntities) {
extMan = new ExtensionManager(entity)
Expand Down Expand Up @@ -119,9 +123,6 @@ class Entities {
use Symfony\Component\HttpFoundation\File\File;
«ENDIF»
use Symfony\Component\Validator\Constraints as Assert;
«IF !getListFieldsEntity.filter[multiple].empty»
use Symfony\Component\Validator\Context\ExecutionContextInterface;
«ENDIF»
«IF !getUniqueDerivedFields.filter[!primaryKey].empty || !getIncomingJoinRelations.filter[unique].empty || !getOutgoingJoinRelations.filter[unique].empty»
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
«ENDIF»
Expand All @@ -131,6 +132,9 @@ class Entities {
«IF !application.targets('1.5'
use «application.appNamespace»\Traits\EntityWorkflowTrait;
«ENDIF»
«IF hasListFieldsEntity»
use «application.appNamespace»\Validator\Constraints as «application.name.formatForCodeCapital»Assert;
«ENDIF»
'''
def private dispatch imports(Entity it) '''
Expand All @@ -150,9 +154,6 @@ class Entities {
use Symfony\Component\HttpFoundation\File\File;
«ENDIF»
use Symfony\Component\Validator\Constraints as Assert;
«IF !getListFieldsEntity.filter[multiple].empty»
use Symfony\Component\Validator\Context\ExecutionContextInterface;
«ENDIF»
«IF !getUniqueDerivedFields.filter[!primaryKey].empty || (hasSluggableFields && slugUnique) || !getIncomingJoinRelations.filter[unique].empty || !getOutgoingJoinRelations.filter[unique].empty || !getUniqueIndexes.empty»
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
«ENDIF»
Expand All @@ -168,6 +169,9 @@ class Entities {
«IF standardFields»
use «application.appNamespace»\TraitsIF loggable»Loggable«ENDIF»StandardFieldsTrait;
«ENDIF»
«IF hasListFieldsEntity»
use «application.appNamespace»\Validator\Constraints as «application.name.formatForCodeCapital»Assert;
«ENDIF»
'''
def private modelEntityBaseImpl(DataObject it, Application app) '''
Expand Down
@@ -0,0 +1,210 @@
package org.zikula.modulestudio.generator.cartridges.zclassic.models.business

import de.guite.modulestudio.metamodel.Application
import org.eclipse.xtext.generator.IFileSystemAccess
import org.zikula.modulestudio.generator.cartridges.zclassic.smallstuff.FileHelper
import org.zikula.modulestudio.generator.extensions.ModelBehaviourExtensions
import org.zikula.modulestudio.generator.extensions.NamingExtensions
import org.zikula.modulestudio.generator.extensions.Utils

class ListEntryValidator {

extension ModelBehaviourExtensions = new ModelBehaviourExtensions
extension NamingExtensions = new NamingExtensions
extension Utils = new Utils

FileHelper fh = new FileHelper

/**
* Creates constraint and validator classes for list field items.
*/
def generate(Application it, IFileSystemAccess fsa) {
println('Generating list entry constraint and validator classes')
generateClassPair(fsa, getAppSourceLibPath + 'Validator/Constraint/ListEntry.php',
fh.phpFileContent(it, constraintBaseImpl), fh.phpFileContent(it, constraintImpl)
)
generateClassPair(fsa, getAppSourceLibPath + 'Validator/Constraint/ListEntryValidator.php',
fh.phpFileContent(it, validatorBaseImpl), fh.phpFileContent(it, validatorImpl)
)
}

def private constraintBaseImpl(Application it) '''
namespace «appNamespace»\Validator\Constraint\Base;

use Symfony\Component\Validator\Constraint;

/**
* List entry validation constraint.
*/
abstract class AbstractListEntry extends Constraint
{
/**
* Entity name
* @var string
*/
public $entityName = '';

/**
* Property name
* @var string
*/
public $propertyName = '';

/**
* Whether multiple list values are allowed or not
* @var boolean
*/
public $multiple = false;

/**
* Minimum amount of values for multiple lists
* @var integer
*/
public $min;

/**
* Maximum amount of values for multiple lists
* @var integer
*/
public $max;

/**
* @inheritDoc
*/
public function validatedBy()
{
return 'zikula_routes_module.validator.list_entry.validator';
}
}
'''
def private constraintImpl(Application it) '''
namespace «appNamespace»\Validator\Constraint;

use «appNamespace»\Validator\Constraint\Base\AbstractListEntry;

/**
* List entry validation constraint.
*
* @Annotation
*/
class ListEntry extends AbstractListEntry
{
// here you can customise the constraint
}
'''
def private validatorBaseImpl(Application it) '''
namespace «appNamespace»\Validator\Constraint\Base;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Zikula\Common\Translator\TranslatorInterface;
use Zikula\Common\Translator\TranslatorTrait;
use «appNamespace»\Helper\ListEntriesHelper;

/**
* List entry validator.
*/
abstract class AbstractListEntryValidator extends ConstraintValidator
{
use TranslatorTrait;

/**
* @var ListEntriesHelper
*/
protected $listEntriesHelper;

/**
* ListEntryValidator constructor.
*
* @param TranslatorInterface $translator Translator service instance
* @param ListEntriesHelper $listEntriesHelper ListEntriesHelper service instance
*/
public function __construct(TranslatorInterface $translator, ListEntriesHelper $listEntriesHelper)
{
$this->setTranslator($translator);
$this->listEntriesHelper = $listEntriesHelper;
}

«setTranslatorMethod»

/**
* @inheritDoc
*/
public function validate($value, Constraint $constraint)
{
if (null === $value) {
return;
}

$listEntries = $this->listEntriesHelper->getEntries($constraint->entityName, $constraint->propertyName);
$allowedValues = [];
foreach ($listEntries as $entry) {
$allowedValues[] = $entry['value'];
}

if (!$constraint->multiple) {
// single-valued list
if (!in_array($value, $allowedValues, true)) {
$this->context->buildViolation(
$this->__f('The value "%value%" is not allowed for the "%property%" property.', [
'%value%' => $value,
'%property%' => $contraint->propertyName
])
)->addViolation();
}

return;
}

// multi-values list
$selected = explode('###', $value);
foreach ($selected as $singleValue) {
if ($singleValue == '') {
continue;
}
if (!in_array($singleValue, $allowedValues, true)) {
$this->context->buildViolation(
$this->__f('The value "%value%" is not allowed for the "%property%" property.', [
'%value%' => $singleValue,
'%property%' => $contraint->propertyName
])
)->addViolation();
}
}

$count = count($value);

if (null !== $constraint->min && $count < $constraint->min) {
$this->context->buildViolation(
$this->__fn('You must select at least "%limit%" choice.', 'You must select at least "%limit%" choices.', $count, [
'%limit%' => $constraint->min
])
)->addViolation();
}
if (null !== $constraint->max && $count > $constraint->max) {
$this->context->buildViolation(
$this->__fn('You must select at most "%limit%" choice.', 'You must select at most "%limit%" choices.', $count, [
'%limit%' => $constraint->max
])
)->addViolation();
}
}
}
'''
def private validatorImpl(Application it) '''
namespace «appNamespace»\Validator\Constraint;

use «appNamespace»\Validator\Constraint\Base\AbstractListEntryValidator;

/**
* List entry validator.
*/
class ListEntryValidator extends AbstractListEntryValidator
{
// here you can customise the validator
}
'''
}

0 comments on commit 0c9f5c5

Please sign in to comment.