Commit 3ef77306 authored by Tino Goratsch's avatar Tino Goratsch

save current work in progress at reimplementing the form validation handling

parent 0dfc66c7
......@@ -8,6 +8,11 @@ namespace ACP3\Core\Exceptions;
*/
class ValidationFailed extends \Exception
{
/**
* ValidationFailed constructor.
*
* @param array $message
*/
public function __construct($message)
{
parent::__construct(serialize($message));
......
......@@ -2,6 +2,7 @@
namespace ACP3\Core;
use ACP3\Core\Helpers\DataGrid\DependencyInjection\RegisterColumnRendererPass;
use ACP3\Core\Validator\DependencyInjection\RegisterValidationRulesPass;
use ACP3\Core\View\Renderer\Smarty\DependencyInjection\RegisterPluginsPass;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
......@@ -26,6 +27,7 @@ class ServiceContainerBuilder
$containerBuilder->addCompilerPass(new RegisterListenersPass('core.eventDispatcher', 'core.eventListener', 'core.eventSubscriber'));
$containerBuilder->addCompilerPass(new RegisterPluginsPass());
$containerBuilder->addCompilerPass(new RegisterColumnRendererPass());
$containerBuilder->addCompilerPass(new RegisterValidationRulesPass());
$loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__));
$loader->load(CLASSES_DIR . 'config/services.yml');
......
<?php
namespace ACP3\Core\Validator\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Class RegisterValidationRulesPass
* @package ACP3\Core\Validator\DependencyInjection
*/
class RegisterValidationRulesPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* @param ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
{
$definition = $container->findDefinition('core.validator');
$plugins = $container->findTaggedServiceIds('core.validator.validation_rule');
foreach ($plugins as $serviceId => $tags) {
$definition->addMethodCall('registerValidationRule', [new Reference($serviceId)]);
}
}
}
\ No newline at end of file
<?php
namespace ACP3\Core\Validator\ValidationRules;
use ACP3\Core\Validator\Validator;
/**
* Class AbstractValidationRule
* @package ACP3\Core\Validator\ValidationRules
*/
abstract class AbstractValidationRule implements ValidationRuleInterface
{
/**
* @var string
*/
protected $message = '';
/**
* @inheritdoc
*/
public function getName()
{
return static::NAME;
}
/**
* @inheritdoc
*/
public function getMessage()
{
return $this->message;
}
/**
* @inheritdoc
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* @inheritdoc
*/
public function validate(Validator $validator, $data, $field = '', array $extra = [])
{
if (!$this->isValid($data, $field, $extra)) {
$validator->addError($this->getMessage(), $field);
}
}
}
\ No newline at end of file
<?php
namespace ACP3\Core\Validator\ValidationRules;
/**
* Class IntegerValidationRule
* @package ACP3\Core\Validator\ValidationRules
*/
class IntegerValidationRule extends AbstractValidationRule
{
const NAME = 'integer';
/**
* @inheritdoc
*/
public function isValid($data, $field = '', array $extra = [])
{
if (is_array($data) && array_key_exists($field, $data)) {
return $this->checkAgainstPattern($data[$field]);
}
return $this->checkAgainstPattern($field);
}
/**
* @param mixed $value
*
* @return bool
*/
protected function checkAgainstPattern($value)
{
return preg_match('/^(\d+)$/', $value) === 1;
}
}
\ No newline at end of file
<?php
namespace ACP3\Core\Validator\ValidationRules;
/**
* Class MinLengthValidationRule
* @package ACP3\Core\Validator\ValidationRules
*/
class MinLengthValidationRule extends AbstractValidationRule
{
const NAME = 'min_length';
/**
* @inheritdoc
*/
public function isValid($data, $field = '', array $extra = [])
{
if (is_array($data) && array_key_exists($field, $data)) {
return $this->checkMinLength($data[$field], $extra['length']);
}
return $this->checkMinLength($field, $extra['length']);
}
/**
* @param string $value
* @param integer $length
*
* @return bool
*/
protected function checkMinLength($value, $length)
{
return mb_strlen($value) >= $length;
}
}
\ No newline at end of file
<?php
namespace ACP3\Core\Validator\ValidationRules;
use \ACP3\Core\Validator\Validator;
/**
* Interface ValidationRuleInterface
* @package ACP3\Core\Validator\ValidationRules
*/
interface ValidationRuleInterface
{
const NAME = '';
/**
* @return string
*/
public function getName();
/**
* @return string
*/
public function getMessage();
/**
* @param string $message
*
* @return $this
*/
public function setMessage($message);
/**
* @param \ACP3\Core\Validator\Validator $validator
* @param mixed $data
* @param string $field
* @param array $extra
*
* @return
*/
public function validate(Validator $validator, $data, $field = '', array $extra = []);
/**
* @param mixed $data
* @param string $field
* @param array $extra
*
* @return boolean
*/
public function isValid($data, $field = '', array $extra = []);
}
\ No newline at end of file
<?php
namespace ACP3\Core\Validator;
use ACP3\Core\Exceptions\ValidationFailed;
use ACP3\Core\Validator\ValidationRules\ValidationRuleInterface;
/**
* Class Validator
* @package ACP3\Core\Validator
*/
class Validator
{
/**
* @var \ACP3\Core\Validator\ValidationRules\ValidationRuleInterface[]
*/
protected $validationRules = [];
/**
* @var array
*/
protected $errors = [];
/**
* @var array
*/
protected $constraints = [];
/**
* @param \ACP3\Core\Validator\ValidationRules\ValidationRuleInterface $validationRule
*
* @return $this
*/
public function registerValidationRule(ValidationRuleInterface $validationRule)
{
$this->validationRules[$validationRule->getName()] = $validationRule;
return $this;
}
/**
* @return array
*/
protected function getDefaultConstraintParams()
{
return [
'data' => null,
'field' => '',
'message' => '',
'extra' => []
];
}
/**
* @param string $validationRuleName
* @param array $params
*
* @return $this
*/
public function addConstraint($validationRuleName, array $params)
{
$key = serialize([
'rule' => $validationRuleName,
$params
]);
$this->constraints[$key] = array_merge($this->getDefaultConstraintParams(), $params);
return $this;
}
/**
* @param string $message
* @param string $field
*
* @return $this
*/
public function addError($message, $field = '')
{
if (!empty($field)) {
$this->errors[$field] = $message;
} else {
$this->errors[] = $message;
}
return $this;
}
public function validate()
{
$this->errors = [];
foreach ($this->constraints as $key => $params) {
$key = unserialize($key);
if (isset($this->validationRules[$key['rule']])) {
$validationRule = $this->validationRules[$key['rule']];
if (!empty($params['message'])) {
$validationRule->setMessage($params['message']);
}
$validationRule->validate(
$this,
$params['data'],
$params['field'],
$params['extra']
);
}
}
if ($this->hasErrors()) {
throw new ValidationFailed($this->errors);
}
}
/**
* @param string $validationRuleName
* @param mixed $field
*
* @return bool
*/
public function is($validationRuleName, $field)
{
if (isset($this->validationRules[$validationRuleName])) {
return $this->validationRules[$validationRuleName]->isValid($field);
}
return false;
}
/**
* @return bool
*/
protected function hasErrors()
{
return !empty($this->errors);
}
}
\ No newline at end of file
services:
core.validator:
class: ACP3\Core\Validator\Validator
core.validator.validation_rules.integer_validation_rule:
class: ACP3\Core\Validator\ValidationRules\IntegerValidationRule
tags:
- { name: core.validator.validation_rule }
core.validator.validation_rules.min_length_validation_rule:
class: ACP3\Core\Validator\ValidationRules\MinLengthValidationRule
tags:
- { name: core.validator.validation_rule }
core.validator.abstract:
abstract: true
arguments: ['@core.lang', '@core.validator.rules.misc']
......
......@@ -48,7 +48,7 @@ services:
articles.validator:
class: %articles.validator.fqdn%
arguments: ['@core.lang', '@core.validator.rules.misc', '@core.validator.rules.router.aliases', '@core.validator.rules.date', '@core.acl']
arguments: ['@core.lang', @core.validator, '@core.validator.rules.misc', '@core.validator.rules.router.aliases', '@core.validator.rules.date', '@core.acl']
calls:
- ['setMenuItemRepository', ['@?menus.model.menuitemrepository']]
......
......@@ -22,9 +22,14 @@ class Validator extends Core\Validator\AbstractValidator
* @var \ACP3\Core\ACL
*/
protected $acl;
/**
* @var \ACP3\Core\Validator\Validator
*/
protected $validator;
/**
* @param \ACP3\Core\Lang $lang
* @param \ACP3\Core\Validator\Validator $validator
* @param \ACP3\Core\Validator\Rules\Misc $validate
* @param \ACP3\Core\Validator\Rules\Router\Aliases $aliasesValidator
* @param \ACP3\Core\Validator\Rules\Date $dateValidator
......@@ -32,6 +37,7 @@ class Validator extends Core\Validator\AbstractValidator
*/
public function __construct(
Core\Lang $lang,
Core\Validator\Validator $validator,
Core\Validator\Rules\Misc $validate,
Core\Validator\Rules\Router\Aliases $aliasesValidator,
Core\Validator\Rules\Date $dateValidator,
......@@ -39,6 +45,7 @@ class Validator extends Core\Validator\AbstractValidator
{
parent::__construct($lang, $validate);
$this->validator = $validator;
$this->aliasesValidator = $aliasesValidator;
$this->dateValidator = $dateValidator;
$this->acl = $acl;
......@@ -71,12 +78,28 @@ class Validator extends Core\Validator\AbstractValidator
if ($this->dateValidator->date($formData['start'], $formData['end']) === false) {
$this->errors['date'] = $this->lang->t('system', 'select_date');
}
if (strlen($formData['title']) < 3) {
$this->errors['title'] = $this->lang->t('articles', 'title_to_short');
}
if (strlen($formData['text']) < 3) {
$this->errors['text'] = $this->lang->t('articles', 'text_to_short');
}
$this->validator
->addConstraint(
Core\Validator\ValidationRules\MinLengthValidationRule::NAME,
[
'data' => $formData,
'field' => 'title',
'message' => $this->lang->t('articles', 'title_to_short'),
'extra' => [
'length' => 3
]
])
->addConstraint(
Core\Validator\ValidationRules\MinLengthValidationRule::NAME,
[
'data' => $formData,
'field' => 'text',
'message' => $this->lang->t('articles', 'text_to_short'),
'extra' => [
'length' => 3
]
]
);
if ($this->acl->hasPermission('admin/menus/items/create') === true && isset($formData['create']) === true) {
$this->validateMenuItem($formData);
}
......@@ -84,6 +107,8 @@ class Validator extends Core\Validator\AbstractValidator
$this->errors['alias'] = $this->lang->t('seo', 'alias_unallowed_characters_or_exists');
}
$this->validator->validate();
$this->_checkForFailedValidation();
}
......@@ -93,9 +118,14 @@ class Validator extends Core\Validator\AbstractValidator
protected function validateMenuItem(array $formData)
{
if ($formData['create'] == 1) {
if ($this->validate->isNumber($formData['block_id']) === false) {
$this->errors['block-id'] = $this->lang->t('menus', 'select_menu_bar');
}
$this->validator->addConstraint(
Core\Validator\ValidationRules\IntegerValidationRule::NAME,
[
'data' => $formData,
'field' => 'block_id',
'message' => $this->lang->t('menus', 'select_menu_bar')
]
);
if (!empty($formData['parent_id']) && $this->validate->isNumber($formData['parent_id']) === false) {
$this->errors['parent-id'] = $this->lang->t('menus', 'select_superior_page');
}
......@@ -103,7 +133,7 @@ class Validator extends Core\Validator\AbstractValidator
// Überprüfen, ob sich die ausgewählte übergeordnete Seite im selben Block befindet
$parentBlock = $this->menuItemRepository->getMenuItemBlockIdById($formData['parent_id']);
if (!empty($parentBlock) && $parentBlock != $formData['block_id']) {
$this->errors['parent_id'] = $this->lang->t('menus', 'superior_page_not_allowed');
$this->errors['parent-id'] = $this->lang->t('menus', 'superior_page_not_allowed');
}
}
if ($formData['display'] != 0 && $formData['display'] != 1) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment