mrynarzewski / dictionary-bundle
Symfony bundle for managing reusable dictionaries and dictionary items.
Package info
bitbucket.org/mrynarzewski/symfony-dictionary-bundle
Type:symfony-bundle
pkg:composer/mrynarzewski/dictionary-bundle
Requires
- php: ^8.2
- doctrine/doctrine-bundle: ^2.13
- doctrine/orm: ^2.17 || ^3.0
- symfony/form: ^6.4 || ^7.0
- symfony/framework-bundle: ^6.4 || ^7.0
- symfony/validator: ^6.4 || ^7.0
Requires (Dev)
None
Suggests
- doctrine/doctrine-migrations-bundle: Needed to execute the bundled Doctrine migration in Symfony applications.
Provides
None
Conflicts
None
Replaces
None
README
Reusable Symfony bundle for storing business dictionaries and dictionary items in Doctrine.
What was recently changed
- minimum PHP requirement raised to
^8.2 - dependency constraints tightened for Symfony
6.4/7.xand Doctrine - Doctrine mapping migrated to PHP attributes
- custom validator fixed to validate dictionary item values correctly
- Docker-based development environment added
Package scope
The bundle provides:
DictionaryandDictionaryItemDoctrine entities- repositories for querying dictionary items
- services for creating and updating dictionaries and items
BelongToDictionaryvalidator for checking whether a scalar value exists in a given dictionaryDictionaryItemTypeform type
Deletion is intentionally blocked by the services, so the bundle treats dictionaries as reference data.
Installation in a Symfony project
- Install the bundle with Composer. Choose one of the following options:
Standard Composer installation:
composer require mrynarzewski/dictionary-bundle
Local development with a Composer path repository:
{
"repositories": [
{
"type": "path",
"url": "../symfony-dictionary-bundle"
}
]
}
Then require the package:
composer require mrynarzewski/dictionary-bundle:*
- Register the bundle in
config/bundles.phpif Symfony Flex does not do it automatically:
<?php
return [
Mrynarzewski\DictionaryBundle\MrynarzewskiDictionaryBundle::class => ['all' => true],
];
- Add Doctrine mapping for the bundle entities in
config/packages/doctrine.yaml:
doctrine:
orm:
mappings:
MrynarzewskiDictionaryBundle:
is_bundle: false
type: attribute
dir: '%kernel.project_dir%/vendor/mrynarzewski/dictionary-bundle/Entity'
prefix: 'Mrynarzewski\DictionaryBundle\Entity'
alias: MrynarzewskiDictionaryBundle
- If your application does not use Doctrine migrations yet, install the Symfony integration:
composer require doctrine/doctrine-migrations-bundle
- Run the migrations. The bundle ships its own migration and registers its migrations path automatically when
doctrine/doctrine-migrations-bundleis installed:
php bin/console doctrine:migrations:migrate
Using the bundle
The bundle exposes two Doctrine entities:
Mrynarzewski\DictionaryBundle\Entity\DictionaryMrynarzewski\DictionaryBundle\Entity\DictionaryItem
It also exposes two main services through their interfaces:
Mrynarzewski\DictionaryBundle\Service\DictionaryServiceInterfaceMrynarzewski\DictionaryBundle\Service\DictionaryItemServiceInterface
Creating dictionaries and items
<?php
namespace App\Service;
use Mrynarzewski\DictionaryBundle\Repository\DictionaryRepository;
use Mrynarzewski\DictionaryBundle\Service\DictionaryItemServiceInterface;
use Mrynarzewski\DictionaryBundle\Service\DictionaryServiceInterface;
final class SeedDictionaryService
{
public function __construct(
private readonly DictionaryServiceInterface $dictionaryService,
private readonly DictionaryItemServiceInterface $dictionaryItemService,
private readonly DictionaryRepository $dictionaryRepository,
) {
}
public function seed(): void
{
$dictionary = $this->dictionaryRepository->find('country');
if ($dictionary === null) {
$dictionary = $this->dictionaryService->create('country', 'Countries');
}
$this->dictionaryItemService->create($dictionary, 'PL', 'Poland');
$this->dictionaryItemService->create($dictionary, 'DE', 'Germany');
}
}
Querying items
Use DictionaryRepository to fetch a dictionary and DictionaryItemRepository to fetch or validate items:
$dictionary = $dictionaryRepository->find('country');
$items = $dictionaryItemRepository->getItemsFromDictionary($dictionary);
$exists = $dictionaryItemRepository->existsInDictionaryByItem($dictionary, 'PL');
Validating a field against a dictionary
The bundle includes the BelongToDictionary constraint, which lets you validate a scalar value against an existing dictionary:
<?php
namespace App\Dto;
use Mrynarzewski\DictionaryBundle\Constraints\BelongToDictionary;
final class AddressDto
{
#[BelongToDictionary(dictionary: 'country')]
public ?string $countryCode = null;
}
Form type
The bundle includes a simple DictionaryItemType form type for DictionaryItem entities:
$form = $this->createForm(\Mrynarzewski\DictionaryBundle\Form\DictionaryItemType::class, $dictionaryItem);
Notes
Dictionary::idis a string identifier, for examplecountryorcurrency.- The bundle stores data in the
dictionaryanddictionary_itemtables. - Each
DictionaryItemis unique within a dictionary by the pair(dictionary_id, item). - The services intentionally do not support deletion, so dictionaries should be treated as reference data.
Local development with Docker
Build and start the PHP container:
docker compose up -d --build
Install dependencies inside the container:
docker compose exec app composer install
Run a quick syntax check:
docker compose exec app find . -path ./vendor -prune -o -name '*.php' -print0 | xargs -0 -n1 php -l
Open a shell in the container:
docker compose exec app bash
Notes on compatibility
The bundle now targets modern Symfony applications while keeping a practical compatibility window:
- PHP
^8.2 - Symfony
^6.4 || ^7.0 - Doctrine ORM
^2.17 || ^3.0
The provided Docker image runs PHP 8.4, so you can validate the bundle on a newer runtime even though the library itself supports PHP 8.2+.