PHP code example of phphd / exceptional-validation
1. Go to this page and download the library: Download phphd/exceptional-validation 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/ */
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
#[ExceptionalValidation]
final class RegisterUserCommand
{
#[Capture(LoginAlreadyTakenException::class, 'auth.login.already_taken')]
private string $login;
#[Capture(WeakPasswordException::class, 'auth.password.weak')]
private string $password;
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
use Symfony\Component\Validator\Constraints as Assert;
#[ExceptionalValidation]
final class OrderProductCommand
{
#[Assert\Valid]
private ProductDetails $product;
}
#[ExceptionalValidation]
final class ProductDetails
{
private int $id;
#[Capture(InsufficientStockException::class, 'order.insufficient_stock')]
private string $quantity;
// ...
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
#[ExceptionalValidation]
final class TransferMoneyCommand
{
#[Capture(
BlockedCardException::class,
'wallet.blocked_card',
when: [self::class, 'isWithdrawalCardBlocked'],
)]
private int $withdrawalCardId;
#[Capture(
BlockedCardException::class,
'wallet.blocked_card',
when: [self::class, 'isDepositCardBlocked'],
)]
private int $depositCardId;
public function isWithdrawalCardBlocked(BlockedCardException $exception): bool
{
return $exception->getCardId() === $this->withdrawalCardId;
}
public function isDepositCardBlocked(BlockedCardException $exception): bool
{
return $exception->getCardId() === $this->depositCardId;
}
}
use PhPhD\ExceptionalValidation\Model\Condition\ValueExceptionMatchCondition;
#[ExceptionalValidation]
final class TransferMoneyCommand
{
#[Capture(BlockedCardException::class, 'wallet.blocked_card', condition: ValueExceptionMatchCondition::class)]
private int $withdrawalCardId;
#[Capture(BlockedCardException::class, 'wallet.blocked_card', condition: ValueExceptionMatchCondition::class)]
private int $depositCardId;
}
use DomainException;
use PhPhD\ExceptionalValidation\Model\Condition\Exception\ValueException;
final class BlockedCardException extends DomainException implements ValueException
{
public function __construct(
private Card $card,
) {
parent::__construct();
}
public function getValue(): int
{
return $this->card->getId();
}
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
use Symfony\Component\Validator\Constraints as Assert;
#[ExceptionalValidation]
final class CreateOrderCommand
{
/** @var ProductDetails[] */
#[Assert\Valid]
private array $products;
}
#[ExceptionalValidation]
final class ProductDetails
{
private int $id;
#[Capture(
InsufficientStockException::class,
'order.insufficient_stock',
when: [self::class, 'isStockExceptionForThisProduct'],
)]
private string $quantity;
public function isStockExceptionForThisProduct(InsufficientStockException $exception): bool
{
return $exception->getProductId() === $this->id;
}
}
use DomainException;
use PhPhD\ExceptionalValidation\Formatter\ViolationListException;
use Symfony\Component\Validator\ConstraintViolationListInterface;
final class CardNumberValidationFailedException extends DomainException implements ViolationListException
{
public function __construct(
private readonly string $cardNumber,
private readonly ConstraintViolationListInterface $violationList,
) {
parent::__construct((string)$this->violationList);
}
public function getViolationList(): ConstraintViolationListInterface
{
return $this->violationList;
}
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
use PhPhD\ExceptionalValidation\Formatter\ViolationListExceptionFormatter;
#[ExceptionalValidation]
final class IssueCreditCardCommand
{
#[Capture(
exception: CardNumberValidationFailedException::class,
formatter: ViolationListExceptionFormatter::class,
)]
private string $cardNumber;
}
use PhPhD\ExceptionalValidation\Formatter\ExceptionViolationFormatter;
use PhPhD\ExceptionalValidation\Model\Exception\CapturedException;
use Symfony\Component\Validator\ConstraintViolationInterface;
final class RegistrationViolationsFormatter implements ExceptionViolationFormatter
{
public function __construct(
#[Autowire('@phd_exceptional_validation.violation_formatter.default')]
private ExceptionViolationFormatter $defaultFormatter,
) {
}
/** @return array{ConstraintViolationInterface} */
public function format(CapturedException $capturedException): ConstraintViolationInterface
{
// you can format violations with the default formatter
// and then slightly adjust only necessary parts
[$violation] = $this->defaultFormatter->format($capturedException);
$exception = $capturedException->getException();
if ($exception instanceof LoginAlreadyTakenException) {
$violation = new ConstraintViolation(
$violation->getMessage(),
$violation->getMessageTemplate(),
['loginHolder' => $exception->getLoginHolder()],
// ...
);
}
if ($exception instanceof WeakPasswordException) {
// ...
}
return [$violation];
}
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
#[ExceptionalValidation]
final class RegisterUserCommand
{
#[Capture(
LoginAlreadyTakenException::class,
'auth.login.already_taken',
formatter: RegistrationViolationsFormatter::class,
)]
private string $login;
#[Capture(
WeakPasswordException::class,
'auth.password.weak',
formatter: RegistrationViolationsFormatter::class,
)]
private string $password;
}
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.