Skip to content

Commit

Permalink
add EntityFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
albertborsos committed Jun 28, 2019
1 parent ab8e16b commit 5a5aee6
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 69 deletions.
16 changes: 1 addition & 15 deletions src/interfaces/RepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,11 @@

namespace albertborsos\ddd\interfaces;

use yii\db\ActiveRecordInterface;

interface RepositoryInterface
{
public static function find();

public static function findOne($condition);

public static function findAll($condition);

public static function updateAll($attributes, $condition = null);

public static function deleteAll($condition = null);

public function save(ActiveRecordInterface $model, $runValidation = true, $attributeNames = null);

public function insert(ActiveRecordInterface $model, $runValidation = true, $attributeNames = null);

public function update(ActiveRecordInterface $model, $runValidation = true, $attributeNames = null);

public function delete(ActiveRecordInterface $model);
public function save(BusinessObject $model, $runValidation = true, $attributeNames = null);
}
91 changes: 37 additions & 54 deletions src/models/AbstractRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace albertborsos\ddd\models;

use albertborsos\ddd\interfaces\BusinessObject;
use albertborsos\ddd\interfaces\RepositoryInterface;
use yii\base\Component;
use yii\base\Exception;
Expand All @@ -10,7 +11,15 @@

abstract class AbstractRepository extends Component implements RepositoryInterface
{
abstract protected static function modelClass();
/**
* @return string
*/
abstract protected static function businessModelClass(): string;

/**
* @return string
*/
abstract protected static function dataModelClass(): string;

/**
* @throws Exception
Expand All @@ -19,98 +28,72 @@ abstract protected static function modelClass();
public function init()
{
parent::init();
if (!\Yii::createObject(static::modelClass()) instanceof ActiveRecordInterface) {
throw new Exception(get_called_class() . '::modelClass() must implements `yii\db\ActiveRecordInterface`');
if (!\Yii::createObject(static::dataModelClass()) instanceof ActiveRecordInterface) {
throw new Exception(get_called_class() . '::dataModelClass() must implements `yii\db\ActiveRecordInterface`');
}
if (!\Yii::createObject(static::businessModelClass()) instanceof BusinessObject) {
throw new Exception(get_called_class() . '::businessModelClass() must implements `albertborsos\ddd\interfaces\BusinessObject`');
}
}

/**
* @return ActiveQueryInterface the newly created [[ActiveQueryInterface]] instance.
*/
public static function find()
protected static function find()
{
return call_user_func([static::modelClass(), 'find']);
return call_user_func([static::dataModelClass(), 'find']);
}

/**
* @param $condition
* @return ActiveRecordInterface|null ActiveRecord instance matching the condition, or `null` if nothing matches.
* @return BusinessObject|null
*/
public static function findOne($condition)
{
return call_user_func_array([static::modelClass(), 'findOne'], [$condition]);
$model = call_user_func_array([static::dataModelClass(), 'findOne'], [$condition]);

return EntityFactory::create(static::businessModelClass(), $model);
}

/**
* @param $condition
* @return ActiveRecordInterface[]|array an array of ActiveRecord instance, or an empty array if nothing matches.
* @return BusinessObject[]|array
*/
public static function findAll($condition)
{
return call_user_func_array([static::modelClass(), 'findAll'], [$condition]);
}
$models = call_user_func_array([static::dataModelClass(), 'findAll'], [$condition]);

/**
* @param $attributes
* @param null $condition
* @return int the number of rows updated
*/
public static function updateAll($attributes, $condition = null)
{
return call_user_func_array([static::modelClass(), 'updateAll'], [$attributes, $condition]);
}

/**
* @param null $condition
* @return int the number of rows deleted
*/
public static function deleteAll($condition = null)
{
return call_user_func_array([static::modelClass(), 'deleteAll'], [$condition]);
return EntityFactory::createCollection(static::businessModelClass(), $models);
}

/**
* @param ActiveRecordInterface $model
* @param BusinessObject $model
* @param bool $runValidation
* @param null $attributeNames
* @return bool whether the saving succeeded (i.e. no validation errors occurred).
* @return bool|mixed
* @throws \yii\base\InvalidConfigException
*/
public function save(ActiveRecordInterface $model, $runValidation = true, $attributeNames = null)
public function save(BusinessObject $model, $runValidation = true, $attributeNames = null)
{
return $model->save($runValidation, $attributeNames);
}
/** @var ActiveRecordInterface $activerecord */
$activerecord = \Yii::createObject(static::dataModelClass(), [$model->attributes]);

/**
* @param ActiveRecordInterface $model
* @param bool $runValidation
* @param null $attributeNames
* @return bool whether the attributes are valid and the record is inserted successfully.
*/
public function insert(ActiveRecordInterface $model, $runValidation = true, $attributeNames = null)
{
return $model->insert($runValidation, $attributeNames);
if ($activerecord->save($runValidation, $attributeNames)) {
return $activerecord->getPrimaryKey();
}

return false;
}

/**
* @param ActiveRecordInterface $model
* @param bool $runValidation
* @param null $attributeNames
* @return int|bool the number of rows affected, or `false` if validation fails
* or updating process is stopped for other reasons.
* Note that it is possible that the number of rows affected is 0, even though the
* update execution is successful.
*/
public function update(ActiveRecordInterface $model, $runValidation = true, $attributeNames = null)
{
return $model->update($runValidation, $attributeNames);
}

/**
* @param ActiveRecordInterface $model
* @param BusinessObject $model
* @return int|bool the number of rows deleted, or `false` if the deletion is unsuccessful for some reason.
* Note that it is possible that the number of rows deleted is 0, even though the deletion execution is successful.
*/
public function delete(ActiveRecordInterface $model)
public function delete(BusinessObject $model)
{
return $model->delete();
}
Expand Down
49 changes: 49 additions & 0 deletions src/models/EntityFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace albertborsos\ddd\models;

use albertborsos\ddd\interfaces\BusinessObject;
use yii\base\Component;
use yii\db\ActiveRecordInterface;

class EntityFactory extends Component
{
public static function create($className, ActiveRecordInterface $model)
{
return self::fill(\Yii::createObject($className), $model->attributes);
}

public static function createCollection($className, array $models): array
{
return array_map(function ($model) use ($className) {
$entity = \Yii::createObject($className);

return self::fill($entity, $model->attributes);
}, $models);
}

private static function fill(BusinessObject $entity, array $attributes)
{
$attributes = self::normalizeIdAttributes($attributes);
foreach ($attributes as $attribute => $value) {
if (!property_exists($entity, $attribute)) {
continue;
}

$entity->$attribute = $value;
}

return $entity;
}

private static function normalizeIdAttributes(array $attributes)
{
if (!isset($attributes['_id'])) {
return $attributes;
}

$attributes['id'] = strval($attributes['_id']);

return $attributes;
}
}

0 comments on commit 5a5aee6

Please sign in to comment.