PHP code example of dborsatto / smart-enums

1. Go to this page and download the library: Download dborsatto/smart-enums library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

dborsatto / smart-enums example snippets


class OrderStatus extends \DBorsatto\SmartEnums\AbstractEnum
{
    // First is a list of all possible values, defined as constants
    private const STATUS_OPEN = 'open';
    private const STATUS_SHIPPED = 'shipped';
    private const STATUS_DELIVERED = 'delivered';

    // In this example, the text representation is implemented in a way
    // that can be easily fed into an internationalization system
    // for easy translation, but if you don't need that you can use actual text
    private const STATUSES = [
        self::STATUS_OPEN => 'order_status.open',
        self::STATUS_SHIPPED => 'order_status.shipped',
        self::STATUS_DELIVERED => 'order_status.delivered',
    ];

    // This is the only method you will *need* to implement
    // You need to return an array with available options as keys,
    // and their text representation as values
    protected static function getValues(): array
    {
        return self::STATUSES;
    }
    
    // Even though you could have public constants and create enums using
    // OrderStatus::fromValue(OrderStatus::STATUS_OPEN), we think that's not the right way.
    // We see the constant as an internal representation of the possible value,
    // but the user does not need to be aware of this.
    // Also, from a purely formal point of value, `::fromValue()` can throw an exception
    // if the given value is not available, but calling the method using the constant
    // you are sure that the status is available, yet you still need to handle the exception.
    // By implementing named constructors, you can keep the visibility to private,
    // and there is no need to handle meaningless exceptions.
    public static function open(): self
    {
        return self::newInstance(self::STATUS_OPEN);
    }
    
    public static function shipped(): self
    {
        return self::newInstance(self::STATUS_SHIPPED);
    }
    
    public static function delivered(): self
    {
        return self::newInstance(self::STATUS_DELIVERED);
    }
    
    public function isDelivered(): bool
    {
        return $this->value === self::STATUS_DELIVERED;
    }
    
    public function canBeShipped(): bool
    {
        return $this->value === self::STATUS_OPEN;
    }
    
    public function canBeDelivered(): bool
    {
        return $this->value === self::STATUS_SHIPPED;
    }
    
    /**
     * @throws OrderStatusException
     */
    public function ship(): self
    {
        if (!$this->canBeShipped()) {
            // We recommend creating your own exceptions
            throw OrderStatusException::orderCannotBeShipped();
        }
        
        return self::shipped();
    }
    
    /**
     * @throws OrderStatusException
     */
    public function deliver(): self
    {
        if (!$this->canBeDelivered()) {
            throw OrderStatusException::orderCannotBeDelivered();
        }
        
        return self::delivered();
    }
}

// Elsewhere
$status = OrderStatus::open();
// Will return order_status.open, as defined in the STATUSES constant
echo $status->getDescription();
// ...
try {
    $shippedStatus = $status->ship();
} catch (OrderStatusException $exception) {
    // ...
}

class Order
{
    // ...

    /**
     * @var OrderStatus
     */
    private $status;
    
    // ...

    public function __construct()
    {
        $this->status = OrderStatus::open();
    }
    
    // ...
    
    /**
     * @throws OrderStatusException 
     */
    public function ship(): void
    {
        $this->status = $this->status->ship();
    }
    
    /**
     * @throws OrderStatusException 
     */
    public function delivered(DateTimeImmutable $deliveryDate): void
    {
        $this->status = $this->status->deliver();
        $this->deliveryDate = $deliveryDate;
    }
}

class OrderStatusType extends \DBorsatto\SmartEnums\Bridge\Doctrine\Type\AbstractEnumType
{
    public const NAME = 'order_status_type';

    protected function getEnumClass(): string
    {
       return OrderStatus::class;
    }

    public function getName(): string
    {
        return self::NAME;
    }
}

class Order
{
    // ...

    /**
     * @var OrderStatus
     *
     * @ORM\Column(type="enum_order_status")
     */
    private $status;
}


use DBorsatto\SmartEnums\Bridge\Symfony\Form\Type\EnumType;

class OrderType extends \Symfony\Component\Form\AbstractType
{
    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        // This example is not the best because ideally you would transition
        // an order status manually by calling an entity method,
        // but sometimes you just have to let users pick an option 
        $builder->add('orderStatus', EnumType::class, [
            'enum_class' => OrderStatus::class,
            'label' => 'Status',
        ]);
    }
}


/** @var \Symfony\Component\Validator\Validator\ValidatorInterface $validator */
$violations = $validator->validate($value, [
    new \DBorsatto\SmartEnums\Bridge\Symfony\Validator\EnumConstraint(['enumClass' => Enum::class]),
]);

// EnumFactory acts as a wrapper for when you only have the enum class available,
// but you need guarantees about it being a valid enum
$factory = new \DBorsatto\SmartEnums\EnumFactory(OrderStatus::class);
// At this point, all methods just forward to the actual enum methods
$factory->fromValue('...');
$factory->fromValues([...]);
$factory->all();

// Sometimes you just need to get the enum value and description as an key => value array
// Because this is usually a formatting problem, instead of breaking encapsulation
// and making the enum constant public, use this formatter
$formatter = new \DBorsatto\SmartEnums\EnumFormatter(OrderStatus::class);

// These methods both return array<string, string> values
$formatter->toValueDescriptionList();
$formatter->toDescriptionValueList();