Value Object data types, using ValueObjectHandler
This handler provides the ability to map database fields to Value Object.
use Saschati\ValueObject\Behaviors\ORMBehavior;
use Saschati\ValueObject\Types\ValueObjects\EmailType;
use Saschati\ValueObject\Types\ValueObjects\UuidType;
use Saschati\ValueObject\Helpers\TypeScope;
use Saschati\ValueObject\Scope\Handlers\ValueObjectHandler;
...
class User extends ActiveRecord
{
...
public function behaviors(): array
{
return [
'vo' => [
'class' => ORMBehavior::class,
'attributes' => [
'id' => UuidType::class,
'email' => [
'scope' => TypeScope::VALUE_OBJECT_TYPE, // ValueObjectHandler::class
'type' => EmailType::class,
'reference' => 'db_email',
],
],
],
];
}
...
}
This handler will be applied if the key specification has a ValueObjectInterface and "scope" is specified as VALUE_OBJECT_TYPE in the array.
name | type | description |
---|---|---|
type* | ::class | Must be a valid type that extends ValueObjectInterface |
reference | @attribute, property, #virtual | The attribute or property from which the ValueObject should be formed, and to which the value will be transferred when saved. |
type | description |
---|---|
UuidType::class | Create id object for generate uuid with validation |
EmailType::class | Create email object for validate email |
CollectionType::class | Create collection object from array fields on base "ramsey/collection" |
Base abstract class for custom ValueObject
type | description |
---|---|
EnumType::class | Abstract class for create custom native type |
IdType::class | Abstract class for create custom ids, extends native type |
NativeType::class | Abstract class for create custom native type |
ArrayType::class | Abstract class for create custom json filed ty Value Object type as one to one |
use Saschati\ValueObject\Types\ValueObjects\Interfaces\ValueObjectInterface;
use Saschati\ValueObject\Behaviors\ORMBehavior;
class Name implements ValueObjectInterface
{
/**
* @var string
*/
private string $firstname;
/**
* @var string
*/
private string $lastname;
/**
* @param string $firstname
* @param string $lastname
*/
public function __construct(string $firstname, string $lastname)
{
$this->firstname = $firstname;
$this->lastname = $lastname;
}
/**
* @return string
*/
public function fullName(): string
{
return "{$this->firstname} {$this->lastname}";
}
/**
* @return string
*/
public function firstName(): string
{
return $this->firstname;
}
/**
* @return string
*/
public function lastName(): string
{
return $this->lastname;
}
/**
* Named constructor to make a Value Object from a native value.
*
* @param mixed $value
*
* @return mixed
*/
public static function convertToObjectValue($value): static
{
[$first, $last] = explode(' ', $value);
return new self($first, $last);
}
/**
* Returns the native value of this Value Object.
*
* @return mixed
*/
public function convertToDatabaseValue(): string
{
return $this->fullName();
}
/**
* Returns the string representation of this Value Object.
*
* @return string
*/
public function __toString(): string
{
return $this->fullName();
}
}
class User extends ActiveRecord
{
...
public function behaviors(): array
{
return [
'vo' => [
'class' => ORMBehavior::class,
'attributes' => [
'full_name' => Name::class,
],
],
];
}
...
}
$user = User::find()->one();
echo $user->full_name // Alex Oleny
echo $user->full_name->fistName() // Alex
echo $user->full_name->lastName() // Oleny
Or create enum type (This is the old implementation, for the new one use trait EnumType with enum PHP8.1)
use Saschati\ValueObject\Types\ValueObjects\Abstracts\EnumType;
use Saschati\ValueObject\Behaviors\ORMBehavior;
class Status implements EnumType
{
public const WAIT = 'wait';
public const ACTIVE = 'active';
public const ARCHIVE = 'archive';
/**
* @return boolean
*/
public function isWait(): bool
{
return $this->value === self::WAIT;
}
/**
* @return boolean
*/
public function isActive(): bool
{
return $this->value === self::ACTIVE;
}
/**
* @return boolean
*/
public function isArchive(): bool
{
return $this->value === self::ARCHIVE;
}
}
class User extends ActiveRecord
{
...
public function behaviors(): array
{
return [
'vo' => [
'class' => ORMBehavior::class,
'attributes' => [
'status' => Status::class,
],
],
];
}
...
}
$user = User::find()->one();
echo $user->status // wait
if ($user->status->isWait() === true) {
$user->status = Status::ACTIVE();
}
echo $user->status // active