Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
php-version: [ '8.1' ]
php-version: [ '8.1', '8.2', '8.3' ]

steps:
- name: Checkout source code
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ the functionality you need without compromising the essence of your own domain.
Let's see a very basic example:

```php
use ComplexHeart\Contracts\Domain\Model\ValueObject;
use ComplexHeart\Domain\Model\Traits\IsValueObject;
use ComplexHeart\Contracts\Domain\Model\ValueObject;use ComplexHeart\Domain\Model\IsValueObject;

/**
* Class Color
Expand Down
20 changes: 10 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
{
"name": "complex-heart/domain-model",
"description": "Domain model toolset to properly build Value Objects, Entities, Aggregates and Services.",
"description": "Domain model toolset to properly build Value Objects, Entities and Aggregates.",
"type": "library",
"license": "Apache-2.0",
"authors": [
{
"name": "Unay Santisteban",
"email": "usantisteban@othercode.es"
"email": "usantisteban@othercode.io"
}
],
"minimum-stability": "stable",
"require": {
"php": "^8.1.0",
"php": "^8.0",
"ext-json": "*",
"ramsey/uuid": "^4.1",
"nesbot/carbon": "^2.40",
"illuminate/collections": "^9.0.0",
"illuminate/collections": "^9.0.0|^10.0",
"lambdish/phunctional": "^2.1",
"doctrine/instantiator": "^1.4",
"complex-heart/contracts": "^1.0.0"
"doctrine/instantiator": "^1.0|^2.0",
"complex-heart/contracts": "^1.0"
},
"require-dev": {
"pestphp/pest": "^1.22.3",
"pestphp/pest-plugin-mock": "^1.0.0",
"pestphp/pest-plugin-faker": "^1.0.0",
"phpstan/phpstan": "^1.9.0"
"pestphp/pest": "^1.0|^2.0",
"pestphp/pest-plugin-mock": "^1.0|^2.0",
"pestphp/pest-plugin-faker": "^1.0|^2.0",
"phpstan/phpstan": "^1.0"
},
"autoload": {
"psr-4": {
Expand Down
14 changes: 8 additions & 6 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
cacheDirectory=".phpunit.cache">
<coverage>
<report>
<clover outputFile="./coverage.xml"/>
</report>
Expand All @@ -18,4 +15,9 @@
</testsuite>
</testsuites>
<logging/>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit>
18 changes: 18 additions & 0 deletions src/Errors/ImmutabilityError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace ComplexHeart\Domain\Model\Errors;

use Error;

/**
* Class ImmutabilityError
*
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Errors
*/
class ImmutabilityError extends Error
{

}
18 changes: 0 additions & 18 deletions src/Exceptions/ImmutableException.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Exceptions/InstantiationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Class InstantiationException
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Exceptions
*/
class InstantiationException extends RuntimeException
Expand Down
2 changes: 1 addition & 1 deletion src/Exceptions/InvariantViolation.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Class InvariantViolation
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Exceptions
*/
class InvariantViolation extends Exception
Expand Down
29 changes: 5 additions & 24 deletions src/Traits/IsAggregate.php → src/IsAggregate.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

declare(strict_types=1);

namespace ComplexHeart\Domain\Model\Traits;
namespace ComplexHeart\Domain\Model;

use ComplexHeart\Domain\Model\Traits\HasDomainEvents;

/**
* Trait IsAggregate
Expand All @@ -13,34 +15,13 @@
* @see https://martinfowler.com/bliki/DDD_Aggregate.html
* @see https://martinfowler.com/bliki/EvansClassification.html
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait IsAggregate
{
use HasDomainEvents;
use IsEntity {
withOverrides as private overrideEntity;
}

/**
* Creates a new instance overriding the given attributes and
* propagating the domain events to the new instance.
*
* @param array<string, mixed> $overrides
*
* @return static
*/
protected function withOverrides(array $overrides): static
{
$new = $this->overrideEntity($overrides);

foreach ($this->_domainEvents as $event) {
$new->registerDomainEvent($event);
}

return $new;
}
use IsEntity;

/**
* This method is called by var_dump() when dumping an object to
Expand Down
28 changes: 28 additions & 0 deletions src/IsEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace ComplexHeart\Domain\Model;

use ComplexHeart\Domain\Model\Traits\HasEquality;
use ComplexHeart\Domain\Model\Traits\HasIdentity;

/**
* Trait IsEntity
*
* > Objects that have a distinct identity that runs through time and different representations.
* > -- Martin Fowler
*
* @see https://martinfowler.com/bliki/EvansClassification.html
*
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait IsEntity
{
use IsModel;
use HasIdentity;
use HasEquality {
HasIdentity::hash insteadof HasEquality;
}
}
54 changes: 17 additions & 37 deletions src/Traits/IsModel.php → src/IsModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

declare(strict_types=1);

namespace ComplexHeart\Domain\Model\Traits;
namespace ComplexHeart\Domain\Model;

use ComplexHeart\Domain\Model\Exceptions\InstantiationException;
use RuntimeException;
use Doctrine\Instantiator\Instantiator;
use ComplexHeart\Domain\Model\Traits\HasAttributes;
use ComplexHeart\Domain\Model\Traits\HasInvariants;
use Doctrine\Instantiator\Exception\ExceptionInterface;
use Doctrine\Instantiator\Instantiator;
use RuntimeException;

/**
* Trait IsModel
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait IsModel
Expand All @@ -30,7 +32,17 @@ trait IsModel
*/
protected function initialize(array $source, callable $onFail = null): static
{
$this->hydrate($this->mapSource($source));
// check if the array is indexed or associative.
$isIndexed = fn($source): bool => ([] !== $source) && array_keys($source) === range(0, count($source) - 1);

$source = $isIndexed($source)
// combine the attributes keys with the provided source values.
? array_combine(array_slice(static::attributes(), 0, count($source)), $source)
// return the already mapped array source.
: $source;


$this->hydrate($source);
$this->check($onFail);

return $this;
Expand All @@ -53,36 +65,4 @@ final public static function make(): static
throw new InstantiationException($e->getMessage(), $e->getCode(), $e);
}
}

/**
* Creates a new instance overriding the given values.
*
* @param array<string, mixed> $overrides
*
* @return static
*/
protected function withOverrides(array $overrides): static
{
return self::make(...array_values(array_merge($this->values(), $overrides)));
}

/**
* Map the given source with the actual attributes by position, if
* the provided array is already mapped (assoc) return it directly.
*
* @param array $source
*
* @return array
*/
final protected function mapSource(array $source): array
{
// check if the array is indexed or associative.
$isIndexed = fn($source): bool => ([] !== $source) && array_keys($source) === range(0, count($source) - 1);

return $isIndexed($source)
// combine the attributes keys with the provided source values.
? array_combine(array_slice(static::attributes(), 0, count($source)), $source)
// return the already mapped array source.
: $source;
}
}
8 changes: 6 additions & 2 deletions src/Traits/IsValueObject.php → src/IsValueObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

declare(strict_types=1);

namespace ComplexHeart\Domain\Model\Traits;
namespace ComplexHeart\Domain\Model;

use ComplexHeart\Domain\Model\Traits\HasEquality;
use ComplexHeart\Domain\Model\Traits\HasImmutability;

/**
* Trait IsValueObject
Expand All @@ -14,13 +17,14 @@
* @see https://martinfowler.com/bliki/ValueObject.html
* @see https://martinfowler.com/bliki/EvansClassification.html
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait IsValueObject
{
use IsModel;
use HasEquality;
use HasImmutability;

/**
* Represents the object as String.
Expand Down
8 changes: 4 additions & 4 deletions src/Traits/HasAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Trait HasAttributes
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait HasAttributes
Expand Down Expand Up @@ -133,11 +133,11 @@ protected function canCall(string $method): bool
* $user->name() will access the private attribute name.
*
* @param string $attribute
* @param array $values
*
* @param array $_
* @return mixed|null
* @deprecated will be removed in version 3.0
*/
public function __call(string $attribute, array $values)
public function __call(string $attribute, array $_): mixed
{
return $this->get($attribute);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Traits/HasDomainEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
* @see https://martinfowler.com/eaaDev/DomainEvent.html
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait HasDomainEvents
Expand Down
2 changes: 1 addition & 1 deletion src/Traits/HasEquality.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Trait HasEquality
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait HasEquality
Expand Down
4 changes: 1 addition & 3 deletions src/Traits/HasIdentity.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

namespace ComplexHeart\Domain\Model\Traits;



use ComplexHeart\Contracts\Domain\Model\Identifier;

/**
* Trait HasIdentity
*
* @author Unay Santisteban <usantisteban@othercode.es>
* @author Unay Santisteban <usantisteban@othercode.io>
* @package ComplexHeart\Domain\Model\Traits
*/
trait HasIdentity
Expand Down
Loading