Search by

ufo-tech / doctrine-eav-bundle

Alex Maistrenko

The DoctrineEAVBundle provides a seamless integration of the Entity-Attribute-Value (EAV) model with Doctrine ORM within the Symfony framework

Package info

github.com/UFO-Tech/doctrine-eav-bundle

Homepage

Type:symfony-bundle

pkg:composer/ufo-tech/doctrine-eav-bundle

Statistics

Installs: 261

Dependents: 0

Suggesters: 0

Stars: 5

Open Issues: 0

0.5.2 2026-10-20 17:40 UTC

This package is auto-updated.

Last update: 2026-10-20 17:40:44 UTC


README

Українська

DoctrineEAVBundle integrates the Entity-Attribute-Value (EAV) model with Doctrine ORM in Symfony applications. It is meant for data whose set of attributes is not fixed in advance — product characteristics in e-commerce, configurable catalogs, and similar dynamic data.

Features

  • Dynamic attributes: attach any number of parameters to an entity without changing the database schema.
  • Typed values: string, number, boolean, option list and file values are stored in one table (Doctrine single-table inheritance); the type is chosen from the PHP value.
  • Specifications (variants): an entity has a tree of specifications; a child specification inherits its parent's values and overrides only what differs.
  • Localization: values and options can be stored per locale with fallback to the default locale; categories are translatable.
  • Filtering and search: ready-made services for faceted filtering (available parameters, values and counts) and search over specification names and values, backed by SQL views.
  • Categories: tree-structured, translatable categories with their own filter sets.

Requirements

  • PHP 8.3+
  • Symfony 7
  • Doctrine ORM, DoctrineBundle, DoctrineMigrationsBundle
  • MySQL — the SQL views use recursive CTEs, window functions and JSON functions (MySQL 8.0+). Other databases are not supported.

Installation

composer require ufo-tech/doctrine-eav-bundle

If the Symfony Flex recipe was not applied, register the bundle manually in config/bundles.php:

return [
    // ...
    Ufo\EAV\UfoEAVBundle::class => ['all' => true],
];

The bundle configures Doctrine by itself: it registers the mapping of its entities, the enum DBAL type, and the DQL functions it needs (JSON_*, POWER, COUNT_SLASHES). No extra configuration is required.

Setup

1. Create your entities

EavEntity and EavCategory are mapped superclasses — extend them in your application:

use Doctrine\ORM\Mapping as ORM;
use Ufo\EAV\Entity\EavEntity;

#[ORM\Entity]
#[ORM\Table(name: 'product')]
class Product extends EavEntity
{
}

Relations from the bundle's tables are redirected to your table automatically during schema generation.

2. Generate and run migrations

php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate

The read side relies on three SQL views (eav_spec_details_view, eav_spec_details_json_view, eav_common_params_filter_view). On the first schema generation, if the views do not exist yet, the bundle generates a separate migration that creates them. It can also be generated manually:

php bin/console ufo:eav:create-view-migration

Usage

Writing values

use Ufo\EAV\Entity\Value;
use Ufo\EAV\Services\EavFactoryService;

$product = new Product('T-shirt', article: 'TS-001');
$spec = $product->getMainSpecification();

// $factory is EavFactoryService (autowired)
$spec->setValue($factory->valueForParam($spec, 'color', 'red'));
$spec->setValue($factory->valueForParam($spec, 'weight', 0.25));

// option values
$size = $factory->getParam('size');
$spec->setValue(Value::create($size, [$factory->getOption($size, 'M')]));

// a variant that inherits all values from the main specification
$variant = $product->addSpecification('T-shirt XL', article: 'TS-001-XL');

$em->persist($product);
$em->flush();

// localized value (after the base value is saved)
$spec->setValue($factory->valueForParam($spec, 'color', 'червоний', locale: 'uk'));
$em->flush();

Reading: $spec->getValue('color') or $spec->getValue('color', 'uk') (falls back to the default-locale value).

Filtering

use Ufo\EAV\Services\FilterDataFactory;
use Ufo\EAV\Services\FilterService;

// "param1=value1,value2;param2=value3"
$filterData = $filterDataFactory->fromFilterRow('color=red,blue;size=M');
// or: $filterDataFactory->fromArray(['color' => ['red', 'blue']]);

$specs   = $filterService->applyFilterData($filterData)->getSpecs(page: 1, limit: 20);
$filters = $filterService->getCommonFilters(); // available params, values and counts

Search

use Ufo\EAV\Services\SearchService;

$results = $searchService->search('red', $filterData);

License

MIT — see LICENSE.