umanit / doctrine-singleton-bundle
Singleton entities working with Doctrine and Sonata
Installs: 7 142
Dependents: 0
Suggesters: 0
Security: 0
Stars: 6
Watchers: 6
Forks: 4
Open Issues: 1
Type:symfony-bundle
pkg:composer/umanit/doctrine-singleton-bundle
Requires
- php: >=8.0
- doctrine/doctrine-bundle: ^2.7
- doctrine/orm: ^2.13|^3.0
- symfony/framework-bundle: >=5.0
README
This bundle intends to easily create complex singleton entities (totally unique, or based on some properties). Sonata Admin friendly with automatic integration.
Install
Register the bundle to your 'app/AppKernel.php'
new Umanit\DoctrineSingletonBundle\UmanitDoctrineSingletonBundle(),
That's it!
Usage
Tell that your entity is a singleton
Just need to implement the Umanit\DoctrineSingletonBundle\Model\SingletonInterface
<?php namespace App\Entity\Content; use Doctrine\ORM\Mapping as ORM; use Umanit\DoctrineSingletonBundle\Model\SingletonInterface; #[ORM\Table(name="page")] class Page implements SingletonInterface { }
Now, if you try to create 2 entities of type "Page", you'll get a NonUniqueException
More complex unicity
If you want to implement a more complex unicity, for example, you want the entity to be unique per local, you can subscribe to the
FilterSingletonEvent::SINGLETON_FILTER_EVENT event to modify the filters (filters are used in a findBy() clause)
e.g (from TranslationBundle)
<?php namespace Umanit\TranslationBundle\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Umanit\DoctrineSingletonBundle\Event\FilterSingletonEvent; use Umanit\TranslationBundle\Doctrine\Model\TranslatableInterface; class SingletonSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents() { return [FilterSingletonEvent::SINGLETON_FILTER_EVENT => ['onFilterEvent']]; } public function onFilterEvent(FilterSingletonEvent $event) { $entity = $event->getEntity(); $filters = $event->getFilters(); if ($entity instanceof TranslatableInterface) { $filters['locale'] = $entity->getLocale(); } $event->setFilters($filters); } }
services.yml
services: umanit_translation.event_subscriber.doctrine_singleton_filter: class: Umanit\TranslationBundle\EventSubscriber\SingletonSubscriber tags: - { name: kernel.event_subscriber }
Get singleton
In order to get your singleton instances, you can use the provided helpers for your PHP code or twig :
<?php $this->get('umanit_doctrine_singleton.helper')->getSingleton('App\Entity\Page::class');
{% set singleton = get_singleton('App\\Entity\\Page') %}
The method getSingleton($className, array $filters = [], $instantiateIfNotFound = false) can take from 1 to 3 arguments :
- $className: FQCN of the class to get
- $filters: Filters to apply to get the singleton (e.g. :- getSingleton("MyClass", ["locale" => "en"]))
- $instantiateIfNotFound: If the entity is not found, returns an empty entity instead of- null
Integrating into SonataAdmin
The bundle will automatically remove add and list button from the list and the edit view.
If you use the UmanitDoctrineSingletonBundle:Sonata\SingletonCRUD as a controller for your admin class, you'll have a redirection
to create if there's no entity found, to edit if there's only one, and to list if you have more than one.
e.g :
app.admin.page: class: App\Admin\PageAdmin arguments: [~, App\Entity\Content\Page, UmanitDoctrineSingletonBundle:Sonata\SingletonCRUD ] tags: - { name: sonata.admin, manager_type: orm, group: 'Content', label: 'Page' }