Download the PHP package andanteproject/nullable-embeddable-bundle without Composer
On this page you can find all versions of the php package andanteproject/nullable-embeddable-bundle. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download andanteproject/nullable-embeddable-bundle
More information about andanteproject/nullable-embeddable-bundle
Files in andanteproject/nullable-embeddable-bundle
Package nullable-embeddable-bundle
Short Description A Symfony Bundle to handle nullable embeddables with Doctrine
License MIT
Informations about the package nullable-embeddable-bundle

Nullable Embeddable Bundle
Symfony Bundle - AndanteProject
A Symfony Bundle that extends Doctrine Embeddables to allow them to be nullable with custom business logic to precisely determine their null state, handling null and uninitialized properties, addressing a common limitation in Doctrine ORM.
Introduction
Doctrine Embeddables are powerful for encapsulating value objects, but they inherently cannot be null. This bundle provides a flexible solution to this limitation by introducing the #[NullableEmbeddable] attribute. This attribute allows you to define custom logic, either through a dedicated static anonymous function (PHP 8.5+), to determine when an embeddable object should be considered null. This enables precise control over the null state, even handling uninitialized properties safely.
The bundle works seamlessly with multiple levels of embedded objects, processing from the deepest leaf embeddable up to the root entity.
For example, a Country embeddable can be marked as nullable based on an uninitialized property:
Requirements
- Symfony 5.x–8.x
- PHP 8.1+ (PHP 8.5+ for anonymous function processors)
- Doctrine ORM
Install
Via Composer:
After installation, make sure you have the bundle registered in your Symfony bundles list (config/bundles.php):
This should be done automatically if you are using Symfony Flex. Otherwise, register it manually.
Usage
The core of this bundle is the #[NullableEmbeddable] attribute, which you place on your Doctrine Embeddable classes alongside #[ORM\Embeddable]. This attribute requires a processor argument, which can be either a class implementing static anonymous function (PHP 8.5+).
Processor Interface
For older PHP versions or more complex logic that warrants a dedicated class, you can implement the ProcessorInterface.
Your processor class must implement this interface.
Example: Address Embeddable with Class Processor
And the corresponding AddressEmbeddableProcessor class:
Anonymous Function Processor (PHP 8.5+)
For projects running on PHP 8.5 or newer, the most convenient way to define your nullability logic is using a static anonymous function directly within the #[NullableEmbeddable] attribute. This keeps your business logic co-located with the embeddable definition, avoiding the need for separate processor classes.
Example: Address Embeddable with Anonymous Function Processor
Consider an Address embeddable that should be considered null if all its properties (street, city, country) are null.
In this example, the anonymous function receives a Result enum (Result::SHOULD_BE_NULL or Result::KEEP_INITIALIZED).
Example: Country Embeddable with Anonymous Function Processor
A nested embeddable like Country can also use this approach. Here, Country is considered null if its code property is uninitialized (meaning it was never set, often indicating a new, empty object).
The PropertyAccessor
The PropertyAccessor provided to your processor (or anonymous function) is a specialized tool that allows you to inspect the state of embeddable properties, including whether they are uninitialized. This is particularly useful for non-nullable properties that might not have been set when an object is retrieved from the database or instantiated.
$propertyAccessor->getValue($embeddableObject, 'propertyName'): Safely retrieves the value of a property.$propertyAccessor->isUninitialized($embeddableObject, 'propertyName'): Checks if a property is uninitialized.
The Result Enum
The analyze method of your processor must return one of two values from the Result enum:
Result::SHOULD_BE_NULL: Indicates that the embeddable object should be treated as null. Note that "should" is used because the parent entity might have the embeddable class defined as not nullable. There is no guarantee the parent entity acceptsnullas a value; this depends on database consistency and the user's data model.Result::KEEP_INITIALIZED: Indicates that the embeddable object should remain initialized.
PHPStan Extension
This bundle includes a PHPStan extension that validates #[NullableEmbeddable] classes to ensure they follow best practices for working with Doctrine's nullable embeddable behavior.
Why This Extension is Important
When Doctrine determines that an entire embeddable object should be null (which is what this bundle does), it sets all the embeddable's database columns to NULL. This has important implications for how you structure your embeddable classes:
-
Property Initialization: Properties with non-null default values should be initialized in the constructor, not outside it. This is because Doctrine hydrates entities by skipping the constructor. For example:
-
Nullable Columns: All properties mapped to database columns must be nullable. This can be achieved either by using a PHP nullable type (
?string), which Doctrine automatically infers asnullable: true, or by explicitly settingnullable: truein the#[Column]attribute. This is required because when the embeddable object is null, Doctrine will set all its database columns toNULL. - Nested Embeddables with Defaults: Embedded objects that have explicit non-null default values must be typed as nullable. Uninitialized embedded properties are fine since they remain uninitialized when the parent is null.
Automatic Installation (Recommended)
If you have phpstan/extension-installer installed (which is included in require-dev), the extension will be automatically registered. No additional configuration needed!
Manual Installation
If you don't have phpstan/extension-installer, you can manually include the extension in your phpstan.neon or phpstan.neon.dist:
What the Extension Checks
The PHPStan extension will report errors for:
- Properties with non-null default values outside the constructor - These should be moved to the constructor to avoid hydration issues
- Non-nullable column mappings - Properties with
#[Column]must be nullable, either via PHP nullable type (?Type) or explicitnullable: true - Embedded objects with non-null default values - Embedded properties with explicit defaults must be nullable (uninitialized embedded properties are allowed)
Example
Configuration
The bundle provides a configuration option to enable a cache warmer for improved performance in production environments.
Alternatively, using PHP:
metadata_cache_warmer_enabled(default:false): When set totrue, the bundle will read all#[NullableEmbeddable]attributes during Symfony's cache warmup process. This can speed up subsequent requests by pre-populating the metadata cache. It is recommended to enable this only in your production environment.
Nested Embeddables
This bundle fully supports nested embeddables (e.g., an Address embeddable containing a Country embeddable). The processing logic correctly traverses the embeddable tree, starting from the deepest nested embeddable and working its way up to the root entity.
Built with love ❤️ by AndanteProject team.
All versions of nullable-embeddable-bundle with dependencies
symfony/config Version ^5.0 || ^6.0 || ^7.0 || ^8.0
symfony/http-kernel Version ^5.0 || ^6.0 || ^7.0 || ^8.0
symfony/dependency-injection Version ^5.0 || ^6.0 || ^7.0 || ^8.0
symfony/property-access Version ^5.0 || ^6.0 || ^7.0 || ^8.0
doctrine/orm Version ^2.0 | ^3.0