markdown 一个特性,可以在Laravel中自动转换值对象,而无需Mutator和Accessor。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 一个特性,可以在Laravel中自动转换值对象,而无需Mutator和Accessor。相关的知识,希望对你有一定的参考价值。

<?php

trait CastsValueObjects
{
    protected function castAttribute($key, $value)
    {
        $castToClass = $this->getValueObjectCastType($key);
        // no Value Object? simply pass this up to the parent
        if (!$castToClass) {
            return parent::castAttribute($key, $value);
        }
        // otherwise create a Value Object
        return $castToClass::fromNative($value);
    }

    public function setAttribute($key, $value)
    {
        $castToClass = $this->getValueObjectCastType($key);
        if (!$castToClass) {
            return parent::setAttribute($key, $value);
        }

        // Enforce type defined in $casts
        if (! ($value instanceof $castToClass)) {
            throw new InvalidArgumentException("Attribute '$key' must be an instance of " . $castToClass);
        }

        // now it has the type, store as native value
        return parent::setAttribute($key, $value->getNativeValue());
    }

    private function getValueObjectCastType($key) {
        $casts = $this->getCasts();
        $castToClass = isset($casts[$key]) ? $casts[$key] : null;
        if (class_exists($castToClass)) {
            return $castToClass;
        }
        return null;
    }
}
<?php
// concrete implementation of a Value Object – note that the constructor is `protected`
final class EmailAddress extends NativeType
{
    /**
     * Creates an EmailAddress object given a PHP native string as parameter.
     *
     * @param string $value
     */
    protected function __construct($value)
    {
        $filteredValue = filter_var($value, FILTER_VALIDATE_EMAIL);
        if ($filteredValue === false) {
            throw new \InvalidArgumentException("Invalid argument $value: Not an email address.");
        }
        $this->value = $filteredValue;
    }
}
<?php
// Want to use [PHP Enum](https://github.com/marc-mabe/php-enum)? Use this wrapper:
use MabeEnum\Enum as BaseEnum;

abstract class EnumValueObject extends BaseEnum implements ValueObject, JsonSerializable {

    public static function fromNative($value)
    {
        return static::get($value);
    }
    
    public function sameValueAs(ValueObject $object)
    {
        return $this->is($object);
    }

    public function getNativeValue() {
        return $this->getValue();
    }

    public function jsonSerialize() {
        return $this->getName();
    }
}
<?php
// example of a primitive Value Object
class NativeType implements ValueObject, \JsonSerializable
{
    /**
     * @var mixed
     */
    protected $value;

    protected function __construct($value)
    {
        $this->value = (string)$value;
    }

    /**
     * Named constructor to instantiate a Value Object
     *
     * @param $value
     * @return static
     */
    public static function fromNative($value)
    {
        return new static($value);
    }

    /**
     * Decides whether or not this Value Object is considered equal to another Value Object
     *
     * @param ValueObject $object
     * @return bool
     */
    public function sameValueAs(ValueObject $object) {
        if (false === Util::classEquals($this, $object)) {
            return false;
        }
        return $this->getNativeValue() === $object->getNativeValue();
    }

    /**
     * Returns the raw $value
     *
     * @return mixed
     */
    public function getNativeValue() {
        return $this->value;
    }

    /**
     * Returns the string representation of $value
     *
     * @return string
     */
    public function __toString() {
        return (string)$this->getNativeValue();
    }

    /**
     * Converts the value to JSON
     *
     * @return mixed
     */
    public function jsonSerialize() {
        return $this->getNativeValue();
    }
}
<?php
// could be made inline – for equality comparison), taken from [PHP Value Objects](https://github.com/nicolopignatelli/valueobjects
class Util
{
    /**
     * Tells whether two objects are of the same class
     *
     * @param  object $object_a
     * @param  object $object_b
     * @return bool
     */
    public static function classEquals($object_a, $object_b)
    {
        return \get_class($object_a) === \get_class($object_b);
    }

    /**
     * Returns full namespaced class as string
     *
     * @param $object
     * @return string
     */
    public static function getClassAsString($object)
    {
        return \get_class($object);
    }
}
<?php
interface ValueObject {

    /**
     * Named constructor to make a Value Object from a native value.
     *
     * @param $value
     * @return mixed
     */
    public static function fromNative($value);

    /**
     * Compares two Value Objects and tells if they can be considered equal.
     *
     * @param ValueObject $object
     * @return bool
     */
    public function sameValueAs(ValueObject $object);

    /**
     * Returns the string representation of this Value Object.
     *
     * @return string
     */
    public function __toString();

    /**
     * Returns the native value of this Value Object.
     *
     * @return mixed
     */
    public function getNativeValue();

}
# How to cast Value Objects in Laravel with `$casts`

This is just a gist, because you need to check how your value objects should look like. Use like this:

```php
class User extends Model {
    use CastsValueObjects;
    protected $casts = [
        'email' => EmailAddress::class
    ];
}
```

See files attached to this gist.

以上是关于markdown 一个特性,可以在Laravel中自动转换值对象,而无需Mutator和Accessor。的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 8 和 VueJS 2 中使用 Marked 解析 Markdown

Laravel 可以验证 markdown mime 类型吗?

Laravel项目中使用markdown编辑器及图片粘贴上传七牛云

markdown 在Laravel 5.5中了解有关模型和视图的更多信息

markdown 在Laravel 5.7种子文件中截断具有外键约束的表。

laravel 中引入markdown,html处理插件