Skip to content

Latest commit

 

History

History
242 lines (208 loc) · 7.52 KB

vo.md

File metadata and controls

242 lines (208 loc) · 7.52 KB

Back

Value Object data types, using ValueObjectHandler

This handler provides the ability to map database fields to Value Object.

Usage

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.

List of ValueObjectHandler properties

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.

List of existing ValueObjects

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

Create custom ValueObject

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