Download the PHP package phphd/exceptional-validation without Composer

On this page you can find all versions of the php package phphd/exceptional-validation. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package exceptional-validation

Exceptional Matcher 🏹

💼 Match the Exceptions to the Object's Properties

Build Status Codecov PHPStan level Psalm level Type coverage Packagist downloads Licence

A lightweight bridge from domain exceptions to validation violations.

Exceptional Matcher.svg

Your domain code that processes Dto (i.e. services / entities) can run validation by throwing business exceptions. \ Using Matcher, you can correlate it to the property that originated it – thereby allowing to return precise field-specific validation errors inferred from the exceptions.

Thence it makes up for what was lacking in tools for relating validation exceptions to their originator fields.

Quick Start ⚡

Install 📥

  1. Require via composer:

  2. [Symfony] enable the bundles in the bundles.php:

    Note: PhdExceptionToolkitBundle is a required dependency \ that provides exception unwrapping needful for this library.

  3. [Non-Symfony] configure the container:

    You can use features of this library outside frameworks. \ See Standalone Usage.

Map and Throw 🎯

Mark a command or dto with #[Try_] attribute, and properties with #[Catch_].

#[Try_] lets the matcher know it's included for processing. \ #[Catch_] defines rules about "what" and "how" to catch.

Finally, throw those exceptions from your use-case handler:

Note: UserRegistration embodies both data (DTO) and behavior (Service) over this data, \ effectively attaining well-comprehensible Object-Oriented Design.

These mappings describe what exceptions what properties correlate with.

Here, LoginAlreadyTakenException is bound to the login property, \ while PasswordCompromisedException is bound to the password property.

You can have additional matching conditions beyond just the exception class name. \ See Match Conditions 🖇️.

The equivalent (very rough) simplified manual logic if not using this library:

Catch and Match 🎣

Exceptional Validation is like a parable of fisherman.

One man went out to fish carps. \ Having cast a fishing rod, he waits... \ And there it is! It's biting! \ In anticipation of a catch, he starts reeling up... \ Yet, to his disappointment, it's a fry and not a fish! \ He throws it back.

The second time he casts the line... \ In faith of a good catch, he waits... \ And now at last, he pulls a fine 5-pound carp. \ He takes it home and roasts it to eat.

The code:

The cue to a parable:

Fisherman evaluates the fish against his expectation - \ ExceptionMatcher matches the exception against UserRegistration object.

Fisherman roasts the fish - \ ExceptionMatcher returns the ConstraintViolation list (or custom format) created of the exception.

Fisherman releases the fry - \ ExceptionMatcher didn't match, and the main code throws $exception; back.

Finally, the created ConstraintViolationList contains violation-objects with matched property path, message translation, and invalid value.

You can serialize it into a json-response or render on a form.

Why Exceptional Matcher ✨

Exceptional Matcher opens the way for Exceptional Validation, wherewith you can omit any peripheral validation off of your dto objects, \ and rely solely on validation in real code (services, value objects) – that belongs to and resides in the domain.

Thus, you have a full-fledged domain-embedded validation that naturally expresses itself with the exceptions.

Where is the Power 🚀

Consider another use-case: after registration, the user should be able to update his profile.

Updating the login must ensure its uniqueness in spite of the current user.

Here's what we'd have to do with an upfront attribute-driven validation:

Compare this to #[Catch_] approach and recognize which communicates the intent better:

The first approach is very imperative, verbose. \ The second declaratively states the fact.

Moreover, now you don't restrain yourself with the limitations of the framework. \ You don't have limitations at all. \ Exceptional Validation enables you to implement everything at the highest quality possible.

The mapping for profile update Dto is just as high-level as it was for registration Dto:

No custom validators, no attribute-driven-rules - just pure business description.

The main code is just as simple as it could be, throwing the same elucidated exceptions:

This communicates the design much better than what we've seen thus far.

This is where the power comes from. You don't cram the validation into the framework. \ You broaden the framework so that it embraces your validation in a way that it naturally fits in.

Read more in: Exceptional Validation.

Interaction approaches 🔁

The library provides a few interaction points:

Features 💎

#[Try_] and #[Catch_] attributes allow implementation of very flexible matching rules. \ It's highly recommended to get acquainted with the examples to apprehend the full power of these solutions.

There are two configuration features:

That's really all this library does – matches the exception and formats it (i.e. roasts the fish).

Cheat Sheet 📝

For a cheat-sheet example of configuration, check the following:

Deep analysis 🌊

The matcher automatically picks all nested objects for analysis, provided that they define #[Try_] attribute.

With nested matching with array properties, property paths are formatted differently.

In the example above, when the exception is matched, the path would be items[<index>].<filed>:

When nesting is really deep, the resulting property path of the formatted violation would include all intermediary properties in its path, starting from the root, down to the leaf item where the exception was actually matched.

Need for conditions

Finding a match for the exception in array field is like finding your luggage in the baggage claim \ when everyone else took just the same alike red backpack as you did.

Red Backpack

When many backpacks are as yours, you must know which one is yours.

Similarly, finding a match for BackorderDisabledForCategoryException across ImportProductDto[] must know which one to relate to, lest it would choose the first object by exception's class: condition (i.e. "grab the first red one and go").

To find your backpack, you would look at some other characteristics that discern it from the rest, \ yea, up to the point of opening it and discovering (or not discovering) your stuff in there.

That's what if: condition is there for – to relate an exception to $this particular object.

In our example, we check that the object's category (e.g. stuff in a backpack) is the same as the one we seek for of the exception.

If the category is different, the object is skipped and another is taken for consideration.

The same applies to the products that don't enable backorder (backorderLimit is not filled):

Thus, we prevent false attribution of the exception to an object that had nothing to do with it.

Advanced 🛠️

Standalone Usage 🔧

If you are not using a Symfony framework, you can still have a great advantage of this library.

In your vanilla project, create a Service Container (symfony/dependency-injection is required) \ and use it to get necessary services:

Herein, you create a Container, compile it, and use to get ExceptionMatcher.

Upgrading 👻

The basic upgrade should be performed by Rector using ExceptionalMatcherSetList \ that comes with the library and contains automatic upgrade rules.

To upgrade a project to the latest version of exceptional-matcher, \ make the following configuration to your rector.php file:

Make sure to specify your current version of the library so that upgrade sets will be matched correctly.

You should also check UPGRADE.md for the list of breaking changes and additional instructions.


All versions of exceptional-validation with dependencies

PHP Build Version
Package Version
Requires php Version >=8.1
symfony/validator Version ^6.0 | ^7.0
webmozart/assert Version ^1.11
phphd/exception-toolkit Version ^1.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package phphd/exceptional-validation contains the following files

Loading the files please wait ...