Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
10 / 10 |
CRAP | |
100.00% |
58 / 58 |
DefaultReferenceValidator | |
100.00% |
1 / 1 |
|
100.00% |
10 / 10 |
21 | |
100.00% |
58 / 58 |
validate | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
getEntityName | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getReferenceName | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
error | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
validateForeignEntity | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
validateOnX | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
validateReferenceMappingList | |
100.00% |
1 / 1 |
3 | |
100.00% |
7 / 7 |
|||
validateReferenceMapping | |
100.00% |
1 / 1 |
6 | |
100.00% |
14 / 14 |
|||
validateMappingDBDataTypes | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
|||
validateMappingPHPDataTypes | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
<?php | |
declare(strict_types = 1); | |
namespace Siesta\Validator; | |
use Siesta\Contract\ReferenceValidator; | |
use Siesta\Model\Attribute; | |
use Siesta\Model\DataModel; | |
use Siesta\Model\Entity; | |
use Siesta\Model\Reference; | |
use Siesta\Model\ReferenceMapping; | |
use Siesta\Model\ValidationLogger; | |
use Siesta\XML\XMLReference; | |
/** | |
* @author Gregor Müller | |
*/ | |
class DefaultReferenceValidator implements ReferenceValidator | |
{ | |
const ERROR_INVALID_FOREIGN_TABLE = "Entity '%s' Reference '%s' points to not defined table %s"; | |
const ERROR_INVALID_FOREIGN_TABLE_CODE = 1300; | |
const ERROR_INVALID_ON_X_VALUE = "Entity '%s' Reference '%s' %s has invalid value '%s'"; | |
const ERROR_INVALID_ON_X_VALUD_CODE = 1301; | |
const ERROR_INVALID_LOCAL_REFERENCE = "Entity '%s' Reference '%s' localColumn '%s' can not be resolved"; | |
const ERROR_INVALID_LOCAL_REFERENCE_CODE = 1302; | |
const ERROR_INVALID_FOREIGN_REFERENCE = "Entity '%s' Reference '%s' foreignColumn '%s' can not be resolved"; | |
const ERROR_INVALID_FOREIGN_REFERENCE_CODE = 1303; | |
const ERROR_MAPPING_HAS_NOT_SAME_DB_DATA_TYPE = "Entity '%s' Reference '%s' localColumn and foreignColumn have different datatypes '%s' and '%s'"; | |
const ERROR_MAPPING_HAS_NOT_SAME_DB_DATA_TYPE_CODE = 1304; | |
const ERROR_MAPPING_HAS_NOT_SAME_PHP_DATA_TYPE = "Entity '%s' Reference '%s' localColumn and foreignColumn have different phptypes '%s' and '%s'"; | |
const ERROR_MAPPING_HAS_NOT_SAME_PHP_DATA_TYPE_CODE = 1305; | |
const ERROR_NO_REFERENCE_MAPPING = "Entity '%s' Reference '%s' has no referenceMapping."; | |
const ERROR_NO_REFERENCE_MAPPING_CODE = 1306; | |
const ALLOWED_ON_X = [ | |
"restrict", | |
"cascade", | |
"set null", | |
"no action" | |
]; | |
/** | |
* @var DataModel | |
*/ | |
protected $datamodel; | |
/** | |
* @var Entity | |
*/ | |
protected $entity; | |
/** | |
* @var Reference | |
*/ | |
protected $reference; | |
/** | |
* @var ValidationLogger | |
*/ | |
protected $logger; | |
/** | |
* @param DataModel $dataModel | |
* @param Entity $entity | |
* @param Reference $reference | |
* @param ValidationLogger $logger | |
*/ | |
public function validate(DataModel $dataModel, Entity $entity, Reference $reference, ValidationLogger $logger) | |
{ | |
$this->datamodel = $dataModel; | |
$this->entity = $entity; | |
$this->reference = $reference; | |
$this->logger = $logger; | |
$this->validateForeignEntity(); | |
$this->validateOnX($reference->getOnUpdate(), XMLReference::ON_UPDATE); | |
$this->validateOnX($reference->getOnDelete(), XMLReference::ON_DELETE); | |
$this->validateReferenceMappingList(); | |
} | |
/** | |
* @return string | |
*/ | |
protected function getEntityName() | |
{ | |
return $this->entity->getClassShortName(); | |
} | |
/** | |
* @return string | |
*/ | |
protected function getReferenceName() | |
{ | |
return $this->reference->getName(); | |
} | |
/** | |
* @param string $text | |
* @param string $code | |
*/ | |
protected function error(string $text, int $code) | |
{ | |
$this->logger->error($text, $code); | |
} | |
/** | |
* | |
*/ | |
protected function validateForeignEntity() | |
{ | |
if ($this->reference->getForeignEntity() !== null) { | |
return; | |
} | |
$error = sprintf(self::ERROR_INVALID_FOREIGN_TABLE, $this->getEntityName(), $this->getReferenceName(), $this->reference->getForeignTable()); | |
$this->error($error, self::ERROR_INVALID_FOREIGN_TABLE_CODE); | |
} | |
/** | |
* @param string $onXValue | |
* @param string $onX | |
*/ | |
protected function validateOnX(string $onXValue, string $onX) | |
{ | |
if (in_array($onXValue, self::ALLOWED_ON_X)) { | |
return; | |
} | |
$error = sprintf(self::ERROR_INVALID_ON_X_VALUE, $this->getEntityName(), $this->getReferenceName(), $onX, $onXValue); | |
$this->error($error, self::ERROR_INVALID_ON_X_VALUD_CODE); | |
} | |
/** | |
* | |
*/ | |
protected function validateReferenceMappingList() | |
{ | |
$referenceMappingList = $this->reference->getReferenceMappingList(); | |
if (sizeof($referenceMappingList) === 0) { | |
$error = sprintf(self::ERROR_NO_REFERENCE_MAPPING, $this->getEntityName(), $this->getReferenceName()); | |
$this->error($error, self::ERROR_NO_REFERENCE_MAPPING_CODE); | |
} | |
foreach ($referenceMappingList as $referenceMapping) { | |
$this->validateReferenceMapping($referenceMapping); | |
} | |
} | |
/** | |
* @param ReferenceMapping $referenceMapping | |
*/ | |
protected function validateReferenceMapping(ReferenceMapping $referenceMapping) | |
{ | |
if ($this->reference->getForeignEntity() === null) { | |
return; | |
} | |
$localAttribute = $referenceMapping->getLocalAttribute(); | |
if ($localAttribute === null) { | |
$error = sprintf(self::ERROR_INVALID_LOCAL_REFERENCE, $this->getEntityName(), $this->getReferenceName(), $referenceMapping->getLocalAttributeName()); | |
$this->error($error, self::ERROR_INVALID_LOCAL_REFERENCE_CODE); | |
} | |
$foreignAttribute = $referenceMapping->getForeignAttribute(); | |
if ($foreignAttribute === null) { | |
$error = sprintf(self::ERROR_INVALID_FOREIGN_REFERENCE, $this->getEntityName(), $this->getReferenceName(), $referenceMapping->getForeignAttributeName()); | |
$this->error($error, self::ERROR_INVALID_FOREIGN_REFERENCE_CODE); | |
} | |
if ($foreignAttribute !== null && $localAttribute !== null) { | |
$this->validateMappingDBDataTypes($localAttribute, $foreignAttribute); | |
$this->validateMappingPHPDataTypes($localAttribute, $foreignAttribute); | |
} | |
} | |
/** | |
* @param Attribute $localAttribute | |
* @param Attribute $foreignAttribute | |
*/ | |
protected function validateMappingDBDataTypes(Attribute $localAttribute, Attribute $foreignAttribute) | |
{ | |
$localType = $localAttribute->getDbType(); | |
$foreignType = $foreignAttribute->getDbType(); | |
if ($localType === $foreignType) { | |
return; | |
} | |
$error = sprintf(self::ERROR_MAPPING_HAS_NOT_SAME_DB_DATA_TYPE, $this->getEntityName(), $this->getReferenceName(), $localType, $foreignType); | |
$this->error($error, self::ERROR_MAPPING_HAS_NOT_SAME_DB_DATA_TYPE_CODE); | |
} | |
/** | |
* @param Attribute $localAttribute | |
* @param Attribute $foreignAttribute | |
*/ | |
protected function validateMappingPHPDataTypes(Attribute $localAttribute, Attribute $foreignAttribute) | |
{ | |
$localType = $localAttribute->getPhpType(); | |
$foreignType = $foreignAttribute->getPhpType(); | |
if ($localType === $foreignType) { | |
return; | |
} | |
$error = sprintf(self::ERROR_MAPPING_HAS_NOT_SAME_PHP_DATA_TYPE, $this->getEntityName(), $this->getReferenceName(), $localType, $foreignType); | |
$this->error($error, self::ERROR_MAPPING_HAS_NOT_SAME_PHP_DATA_TYPE_CODE); | |
} | |
} |