Skip to content

Commit

Permalink
add initial exist and unique validators
Browse files Browse the repository at this point in the history
  • Loading branch information
albertborsos committed Sep 9, 2019
1 parent 0dfb809 commit 7206957
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 12 deletions.
8 changes: 5 additions & 3 deletions src/interfaces/RepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ interface RepositoryInterface
public function findById($id): ?EntityInterface;

/**
* @param $id
* @return EntityInterface|null
* @param EntityInterface $entity
* @param array $attributes
* @param $addNotConditionForPrimaryKeys
* @return bool
*/
public function exists(EntityInterface $entity): bool;
public function exists(EntityInterface $entity, $attributes = [], $addNotConditionForPrimaryKeys = false): bool;

/**
* @param EntityInterface $entity
Expand Down
26 changes: 20 additions & 6 deletions src/repositories/AbstractActiveRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use yii\db\ActiveQueryInterface;
use yii\db\ActiveRecord;
use yii\db\ActiveRecordInterface;
use yii\db\conditions\AndCondition;
use yii\db\Connection;
use yii\db\Transaction;

Expand Down Expand Up @@ -127,11 +128,13 @@ public function delete(EntityInterface $entity): bool

/**
* @param EntityInterface $entity
* @param array $attributes
* @param bool $addNotConditionForPrimaryKeys
* @return bool
*/
public function exists(EntityInterface $entity): bool
public function exists(EntityInterface $entity, $attributes = [], $addNotConditionForPrimaryKeys = false): bool
{
return $this->find()->andWhere($this->createFindConditionByEntityKeys($entity))->exists();
return $this->find()->andWhere($this->createFindConditionByEntityKeys($entity, $attributes, true, $addNotConditionForPrimaryKeys))->exists();
}

/**
Expand Down Expand Up @@ -269,24 +272,35 @@ public function beforeDelete(EntityInterface $entity)

/**
* @param EntityInterface $entity
* @param array $keys
* @param bool $skipEmptyAttributes
* @param bool $addNotConditionForPrimaryKeys
* @return array
*/
protected function createFindConditionByEntityKeys(EntityInterface $entity, $skipEmptyAttributes = false): array
protected function createFindConditionByEntityKeys(EntityInterface $entity, $keys = [], $skipEmptyAttributes = false, $addNotConditionForPrimaryKeys = false)
{
$keys = is_array($entity->getPrimaryKey()) ? $entity->getPrimaryKey() : [$entity->getPrimaryKey()];
if (empty($keys)) {
$keys = is_array($entity->getPrimaryKey()) ? $entity->getPrimaryKey() : [$entity->getPrimaryKey()];
}

$condition = [];

array_walk($keys, function ($key) use (&$condition, $entity) {
$condition[$key] = $entity->{$key};
$condition[] = [$key => $entity->{$key}];
});

if ($skipEmptyAttributes) {
$condition = array_filter($condition);
}

return $condition;
if ($addNotConditionForPrimaryKeys) {
$primaryKeys = is_array($entity->getPrimaryKey()) ? $entity->getPrimaryKey() : [$entity->getPrimaryKey()];
array_walk($primaryKeys, function ($key) use (&$condition, $entity) {
$condition[] = ['NOT', [$key => $entity->{$key}]];
});
}

return new AndCondition($condition);
}

/**
Expand Down
8 changes: 5 additions & 3 deletions src/repositories/CacheRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ public function findById($id): ?EntityInterface

/**
* @param EntityInterface $entity
* @return EntityInterface|null
* @param array $attributes
* @param bool $addNotConditionForPrimaryKeys
* @return bool
*/
public function exists(EntityInterface $entity): bool
public function exists(EntityInterface $entity, $attributes = [], $addNotConditionForPrimaryKeys = false): bool
{
return !empty($this->findEntityByKey($entity->getCacheKey()));
return !empty($this->findEntityByKey($entity->getCacheKey($attributes)));
}

/**
Expand Down
32 changes: 32 additions & 0 deletions src/traits/RepositoryPropertyTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace albertborsos\ddd\traits;

use albertborsos\ddd\interfaces\RepositoryInterface;
use yii\base\InvalidConfigException;

trait RepositoryPropertyTrait
{
/** @var string|RepositoryInterface */
public $repository;

/**
* @throws InvalidConfigException
*/
public function init()
{
parent::init();
$this->initRepository();
}

/**
* @throws InvalidConfigException
*/
protected function initRepository(): void
{
$this->repository = \Yii::createObject($this->repository);
if (!$this->repository instanceof RepositoryInterface) {
throw new InvalidConfigException(static::class . '::$repository must implements `' . RepositoryInterface::class . '`');
}
}
}
55 changes: 55 additions & 0 deletions src/validators/ExistValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace albertborsos\ddd\validators;

use albertborsos\ddd\interfaces\EntityInterface;
use albertborsos\ddd\models\AbstractEntity;
use albertborsos\ddd\traits\RepositoryPropertyTrait;

class ExistValidator extends \yii\validators\Validator
{
use RepositoryPropertyTrait;

public $targetAttribute;

public $filter;

public function init()
{
parent::init();
$this->initRepository();
$this->initMessage();
}

/**
* @param AbstractEntity $model
* @param string $attribute
*/
public function validateAttribute($model, $attribute)
{
$entity = $this->initEntity($model, $attribute);
if ($this->repository->exists($entity, [$attribute], !empty($model->id))) {
$this->addError($model, $attribute, $this->message);
}
}

protected function initEntity(EntityInterface $entity, $attribute): EntityInterface
{
$primaryKeys = is_array($entity->getPrimaryKey()) ? $entity->getPrimaryKey() : [$entity->getPrimaryKey()];

$condition = [];

array_walk($primaryKeys, function ($key) use (&$condition, $entity) {
$condition[$key] = $entity->{$key};
});

return $this->repository->hydrate(array_merge($condition, [$attribute => $entity->$attribute]));
}

protected function initMessage(): void
{
if ($this->message === null) {
$this->message = \Yii::t('yii', '{attribute} is invalid.');
}
}
}
10 changes: 10 additions & 0 deletions src/validators/UniqueValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace albertborsos\ddd\validators;

use albertborsos\ddd\traits\RepositoryPropertyTrait;

class UniqueValidator extends \yii\validators\UniqueValidator
{
use RepositoryPropertyTrait;
}

0 comments on commit 7206957

Please sign in to comment.