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]
class RegisterUserCommand
{
#[Capture(LoginAlreadyTakenException::class, 'auth.login.already_taken')]
public string $login;
#[Capture(WeakPasswordException::class, 'auth.password.weak')]
public string $password;
}
use Symfony\Component\Validator\Constraints as Assert;
use App\Validator\Constraints as AppAssert;
class RegisterUserCommand
{
#[AppAssert\UniqueLogin]
public string $login;
#[Assert\PasswordStrength(minScore: 2)]
public string $password;
}
// RegisterUserService
if ($this->userRepository->loginExists($command->login)) {
throw new LoginAlreadyTakenException($command->login);
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
#[ExceptionalValidation]
class PublishMessageCommand
{
#[Capture(MessageNotFoundException::class)]
public string $messageId;
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
use Symfony\Component\Uid\Uuid;
#[ExceptionalValidation]
class ConfirmPackageCommand
{
#[Capture(\InvalidArgumentException::class, from: [Uuid::class, 'fromString'])]
public string $uid;
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
#[ExceptionalValidation]
class TransferMoneyCommand
{
#[Capture(BlockedCardException::class, when: [self::class, 'isWithdrawalCardBlocked'])]
public int $withdrawalCardId;
#[Capture(BlockedCardException::class, when: [self::class, 'isDepositCardBlocked'])]
public 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;
use PhPhD\ExceptionalValidation\Capture;
use PhPhD\ExceptionalValidation\Rule\Object\Property\Capture\Condition\Value\ExceptionValueMatchCondition;
#[ExceptionalValidation]
class TransferMoneyCommand
{
#[Capture(BlockedCardException::class, condition: ExceptionValueMatchCondition::class)]
public int $withdrawalCardId;
#[Capture(BlockedCardException::class, condition: ExceptionValueMatchCondition::class)]
public int $depositCardId;
}
use PhPhD\ExceptionalValidation\Rule\Object\Property\Capture\Condition\Value\ValueException;
class BlockedCardException extends DomainException implements ValueException
{
public function __construct(private Card $card)
{
parent::__construct('card.blocked');
}
public function getValue(): int
{
return $this->card->getId();
}
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
use PhPhD\ExceptionalValidation\Rule\Object\Property\Capture\Condition\Validator\ValidationFailedExceptionMatchCondition;
use Symfony\Component\Validator\Exception\ValidationFailedException;
#[ExceptionalValidation]
class RegisterUserCommand
{
#[Capture(ValidationFailedException::class, from: Password::class, condition: ValidationFailedExceptionMatchCondition::class)]
public string $password;
}
use PhPhD\ExceptionalValidation;
use PhPhD\ExceptionalValidation\Capture;
use Symfony\Component\Validator\Constraints as Assert;
#[ExceptionalValidation]
class CreateOrderCommand
{
/** @var OrderItemDto[] */
#[Assert\Valid]
public array $items;
}
#[ExceptionalValidation]
class OrderItemDto
{
public int $productId;
#[Capture(InsufficientStockException::class, when: [self::class, 'isStockExceptionForThisItem'])]
public string $quantity;
public function isStockExceptionForThisItem(InsufficientStockException $exception): bool
{
return $exception->getProductId() === $this->productId;
}
}
/**
* @var Login $login
* @var Password $password
*/
[$login, $password] = await([
// validate and create an instance of Login
async($this->createLogin(...), $command->getLogin()),
// validate and create an instance of Password
async($this->createPassword(...), $command->getPassword()),
]);
use PhPhD\ExceptionalValidation\Mapper\Validator\Formatter\Item\ViolationList\ViolationListException;
use Symfony\Component\Validator\ConstraintViolationListInterface;
final class CardNumberValidationFailedException extends \RuntimeException 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\Mapper\Validator\Formatter\Item\ViolationList\ViolationListExceptionFormatter;
#[ExceptionalValidation]
class IssueCreditCardCommand
{
#[Capture(
exception: CardNumberValidationFailedException::class,
formatter: ViolationListExceptionFormatter::class,
)]
private string $cardNumber;
}
use PhPhD\ExceptionalValidation\Mapper\Validator\Formatter\Item\ExceptionViolationFormatter;
use PhPhD\ExceptionalValidation\Rule\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
{
// format violation with the default formatter
// and then adjust only the 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;
}
return RectorConfig::configure()
->withPaths([ __DIR__ . '/src'])
->withImportNames(removeUnusedImports: true)
// Upgrading from the version 1.4 to the latest version
->withSets(ExceptionalValidationSetList::fromVersion('1.4')->getSetList());
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.