Skip to content

Commit

Permalink
add TimestampBehavior for entities
Browse files Browse the repository at this point in the history
  • Loading branch information
albertborsos committed Aug 27, 2019
1 parent ab5d030 commit 966a53c
Show file tree
Hide file tree
Showing 14 changed files with 437 additions and 51 deletions.
22 changes: 22 additions & 0 deletions src/base/EntityEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace albertborsos\ddd\base;

/**
* EntityEvent represents the parameter needed by [[Entity]] events.
*
* @since 2.0.0
*/
class EntityEvent extends \yii\base\Event
{
/**
* @var bool whether the entity is in valid status. Defaults to true.
* A entity is in valid status if it passes validations or certain checks.
*/
public $isValid = true;

/**
* @var array
*/
public $dirtyAttributes = [];
}
70 changes: 70 additions & 0 deletions src/behaviors/TimestampBehavior.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace albertborsos\ddd\behaviors;

use albertborsos\ddd\base\EntityEvent;
use albertborsos\ddd\interfaces\EntityInterface;
use yii\base\Event;
use yii\base\InvalidConfigException;

class TimestampBehavior extends \yii\behaviors\TimestampBehavior
{
public $createdAtAttribute = 'createdAt';

public $updatedAtAttribute = 'updatedAt';

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

protected function setDefaultAttributes(): void
{
if (!empty($this->attributes)) {
return;
}

$this->attributes = [
EntityInterface::EVENT_BEFORE_INSERT => [$this->createdAtAttribute, $this->updatedAtAttribute],
EntityInterface::EVENT_BEFORE_UPDATE => $this->updatedAtAttribute,
];
}

/**
* Evaluates the attribute value and assigns it to the current attributes.
* @param Event $event
* @throws InvalidConfigException
*/
public function evaluateAttributes($event)
{
if (!$event instanceof EntityEvent) {
throw new InvalidConfigException(get_class($this) . ' must be used with ' . EntityEvent::class);
}

if (
$this->skipUpdateOnClean
&& $event->name == EntityInterface::EVENT_BEFORE_UPDATE
&& empty($event->dirtyAttributes)
) {
return;
}

if (empty($this->attributes[$event->name])) {
return;
}

$attributes = (array)$this->attributes[$event->name];
$value = $this->getValue($event);
foreach ($attributes as $attribute) {
// ignore attribute names which are not string (e.g. when set by TimestampBehavior::updatedAtAttribute)
if (!is_string($attribute)) {
continue;
}
if ($this->preserveNonEmptyValues && !empty($this->owner->$attribute)) {
continue;
}
$this->owner->$attribute = $value;
}
}
}
4 changes: 3 additions & 1 deletion src/interfaces/ActiveRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use yii\base\Model;
use yii\db\ActiveQueryInterface;
use yii\db\ActiveRecordInterface;
use yii\db\Transaction;

/**
Expand Down Expand Up @@ -48,11 +49,12 @@ public function insert(EntityInterface $entity, $runValidation = true, $attribut

/**
* @param EntityInterface $entity
* @param ActiveRecordInterface|null $activeRecord
* @param bool $runValidation
* @param null $attributeNames
* @return bool
*/
public function update(EntityInterface $entity, $runValidation = true, $attributeNames = null): bool;
public function update(EntityInterface $entity, ActiveRecordInterface $activeRecord = null, $runValidation = true, $attributeNames = null): bool;

/**
* @param EntityInterface $entity
Expand Down
29 changes: 29 additions & 0 deletions src/interfaces/EntityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace albertborsos\ddd\interfaces;

use yii\base\Event;
use yii\base\Model;

/**
Expand All @@ -21,6 +22,25 @@ interface EntityInterface
*/
const EVENT_AFTER_DELETE = 'afterDelete';

/**
* @event EntityEvent an event that is triggered before inserting an entity.
* You may set [[EntityEvent::isValid]] to be `false` to stop the insertion.
*/
const EVENT_BEFORE_INSERT = 'beforeInsert';

/**
* @event EntityEvent an event that is triggered before updating an entity.
* You may set [[EntityEvent::isValid]] to be `false` to stop the update.
*/
const EVENT_BEFORE_UPDATE = 'beforeUpdate';

const EVENT_AFTER_INSERT = 'afterInsert';

const EVENT_AFTER_UPDATE = 'afterUpdate';

const EVENT_BEFORE_DELETE = 'beforeDelete';


/**
* @return string|array
*/
Expand Down Expand Up @@ -87,4 +107,13 @@ public function relationMapping(): array;
* @return array
*/
public function getDataAttributes(): array;

/**
* Triggers an event.
* This method represents the happening of an event. It invokes
* all attached handlers for the event including class-level handlers.
* @param string $name the event name
* @param Event $event the event parameter. If not set, a default [[Event]] object will be created.
*/
public function trigger($name, Event $event = null);
}
1 change: 1 addition & 0 deletions src/models/AbstractEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use albertborsos\ddd\interfaces\EntityInterface;
use yii\base\InvalidConfigException;
use yii\base\Model;
use yii\db\ActiveRecordInterface;
use yii\helpers\Inflector;

/**
Expand Down

0 comments on commit 966a53c

Please sign in to comment.