diff --git a/doc/symfony4.md b/doc/symfony.md
similarity index 69%
rename from doc/symfony4.md
rename to doc/symfony.md
index 04964b47cb..b0fc3a3509 100644
--- a/doc/symfony4.md
+++ b/doc/symfony.md
@@ -1,6 +1,6 @@
-# Install Gedmo Doctrine extensions in Symfony 4
+# Install Gedmo Doctrine extensions in Symfony
-Configure full featured [Doctrine extensions](https://github.com/doctrine-extensions/DoctrineExtensions) for your Symfony 4 project.
+Configure full featured [Doctrine extensions](https://github.com/doctrine-extensions/DoctrineExtensions) for your Symfony project.
This post will show you - how to create a simple configuration file to manage extensions with
ability to use all features it provides.
Interested? then bear with me! and don't be afraid, we're not diving into security component :)
@@ -11,7 +11,7 @@ over management of extensions.
Content:
-- [Symfony 4](#sf4-app) application
+- [Symfony](#sf-app) application
- Extensions metadata [mapping](#ext-mapping)
- Extensions filters [filtering](#ext-filtering)
- Extension [listeners](#ext-listeners)
@@ -19,11 +19,11 @@ Content:
- Some [tips](#more-tips)
- [Alternative](#alternative) over configuration
-
+
-## Symfony 4 application
+## Symfony application
-First of all, we will need a symfony 4 startup application, let's say [symfony-standard edition
+First of all, we will need a symfony startup application, let's say [symfony-standard edition
with composer](https://symfony.com/doc/current/best_practices/creating-the-project.html)
- `composer create-project symfony/skeleton [project name]`
@@ -46,15 +46,15 @@ To do so, add some mapping info to your **doctrine.orm** configuration, edit **c
```yaml
doctrine:
dbal:
-# your dbal config here
+ # your dbal config here
orm:
- auto_generate_proxy_classes: %kernel.debug%
+ auto_generate_proxy_classes: '%kernel.debug%'
auto_mapping: true
-# only these lines are added additionally
+ # only these lines are added additionally
mappings:
translatable:
- type: annotation # or attribute
+ type: attribute # or annotation or xml
alias: Gedmo
prefix: Gedmo\Translatable\Entity
# make sure vendor library location is correct
@@ -79,7 +79,7 @@ to you also. To skip mapping of these entities, you can map **only superclasses*
```yaml
mappings:
translatable:
- type: annotation # or attribute
+ type: attribute # or annotation or xml
alias: Gedmo
prefix: Gedmo\Translatable\Entity
# make sure vendor library location is correct
@@ -101,23 +101,23 @@ everything the extensions provide:
```yaml
# only orm config branch of doctrine
orm:
- auto_generate_proxy_classes: %kernel.debug%
+ auto_generate_proxy_classes: '%kernel.debug%'
auto_mapping: true
-# only these lines are added additionally
+ # only these lines are added additionally
mappings:
translatable:
- type: annotation # or attribute
+ type: attribute # or annotation or xml
alias: Gedmo
prefix: Gedmo\Translatable\Entity
# make sure vendor library location is correct
dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Translatable/Entity"
loggable:
- type: annotation # or attribute
+ type: attribute # or annotation or xml
alias: Gedmo
prefix: Gedmo\Loggable\Entity
dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Loggable/Entity"
tree:
- type: annotation # or attribute
+ type: attribute # or annotation or xml
alias: Gedmo
prefix: Gedmo\Tree\Entity
dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Tree/Entity"
@@ -130,11 +130,11 @@ To do so, add this filter info to your **doctrine.orm** configuration, edit **co
```yaml
doctrine:
dbal:
-# your dbal config here
+ # your dbal config here
orm:
- auto_generate_proxy_classes: %kernel.debug%
+ auto_generate_proxy_classes: '%kernel.debug%'
auto_mapping: true
-# only these lines are added additionally
+ # only these lines are added additionally
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
@@ -155,13 +155,24 @@ services:
gedmo.listener.tree:
class: Gedmo\Tree\TreeListener
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'prePersist'}
+ - { name: doctrine.event_listener, event: 'preUpdate'}
+ - { name: doctrine.event_listener, event: 'preRemove'}
+ - { name: doctrine.event_listener, event: 'onFlush'}
+ - { name: doctrine.event_listener, event: 'loadClassMetadata'}
+ - { name: doctrine.event_listener, event: 'postPersist'}
+ - { name: doctrine.event_listener, event: 'postUpdate'}
+ - { name: doctrine.event_listener, event: 'postRemove'}
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
Gedmo\Translatable\TranslatableListener:
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'postLoad' }
+ - { name: doctrine.event_listener, event: 'postPersist' }
+ - { name: doctrine.event_listener, event: 'preFlush' }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
- [ setDefaultLocale, [ "%locale%" ] ]
@@ -170,46 +181,63 @@ services:
gedmo.listener.timestampable:
class: Gedmo\Timestampable\TimestampableListener
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'prePersist' }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
gedmo.listener.sluggable:
class: Gedmo\Sluggable\SluggableListener
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'prePersist' }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
gedmo.listener.sortable:
class: Gedmo\Sortable\SortableListener
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
+ - { name: doctrine.event_listener, event: 'prePersist' }
+ - { name: doctrine.event_listener, event: 'postPersist' }
+ - { name: doctrine.event_listener, event: 'preUpdate' }
+ - { name: doctrine.event_listener, event: 'postRemove' }
+ - { name: doctrine.event_listener, event: 'postFlush' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
-
+
gedmo.listener.softdeleteable:
class: Gedmo\SoftDeleteable\SoftDeleteableListener
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
Gedmo\Loggable\LoggableListener:
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
+ - { name: doctrine.event_listener, event: 'postPersist' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
Gedmo\Blameable\BlameableListener:
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'prePersist' }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
Gedmo\IpTraceable\IpTraceableListener:
tags:
- - { name: doctrine.event_subscriber, connection: default }
+ - { name: doctrine.event_listener, event: 'prePersist' }
+ - { name: doctrine.event_listener, event: 'onFlush' }
+ - { name: doctrine.event_listener, event: 'loadClassMetadata' }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
@@ -224,15 +252,19 @@ You will need to create this subscriber class if you use **loggable** , **transl
behaviors. This listener will set the **locale used** from request and **username** to
loggable and blameable. So, to finish the setup create **EventSubscriber\DoctrineExtensionSubscriber**
-## Register event subscriber for [Symfony Doctrine MongoDB Bundle](https://github.com/doctrine/DoctrineMongoDBBundle)
+## Register event listener for [Symfony Doctrine MongoDB Bundle](https://github.com/doctrine/DoctrineMongoDBBundle)
-Because DoctrineExtensions does not implement `EventSubscriberInterface` from MongoDBBundle, you need to manually tag
-the listeners. Otherwise, the listeners will not be listening to the triggered events of Doctrine.
+You also need to manually tag the listeners. Otherwise, the listeners will not be listening to the triggered events
+of Doctrine.
```yaml
Gedmo\Loggable\LoggableListener:
- tags:
- - { name: doctrine_mongodb.odm.event_subscriber }
+ tags:
+ - { name: doctrine_mongodb.odm.event_listener, event: 'onFlush' }
+ - { name: doctrine_mongodb.odm.event_listener, event: 'loadClassMetadata' }
+ - { name: doctrine_mongodb.odm.event_listener, event: 'postPersist' }
+ calls:
+ - [ setAnnotationReader, [ "@annotation_reader" ] ]
```
```php
@@ -245,7 +277,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
-class DoctrineExtensionSubscriber implements EventSubscriberInterface
+final class DoctrineExtensionSubscriber implements EventSubscriberInterface
{
/**
* @var BlameableListener
@@ -278,7 +310,7 @@ class DoctrineExtensionSubscriber implements EventSubscriberInterface
}
- public static function getSubscribedEvents()
+ public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => 'onKernelRequest',
@@ -318,13 +350,17 @@ if you do not believe me, let's create a simple entity in our project:
namespace App\Entity;
-use Gedmo\Mapping\Annotation as Gedmo; // gedmo annotations
-use Doctrine\ORM\Mapping as ORM; // doctrine orm annotations
+use DateTimeImmutable;
+use Doctrine\DBAL\Types\Types;
+use Doctrine\ORM\Mapping as ORM;
+use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Entity
* @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
*/
+#[ORM\Entity]
+#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)]
class BlogPost
{
/**
@@ -332,62 +368,72 @@ class BlogPost
* @ORM\Id
* @ORM\Column(length=32, unique=true)
*/
- private $id;
+ #[Gedmo\Slug(fields: ['title', updatable: false, separator: '_'])]
+ #[ORM\Id]
+ #[ORM\Column(lenght: 32, unique: true)]
+ private ?int $id;
/**
* @Gedmo\Translatable
* @ORM\Column(length=64)
*/
- private $title;
+ #[Gedmo\Translatable]
+ #[ORM\Column(length: 64)]
+ private ?string $title;
/**
* @Gedmo\Timestampable(on="create")
- * @ORM\Column(name="created", type="datetime")
+ * @ORM\Column(name="created", type="datetime_immutable")
*/
- private $created;
+ #[Gedmo\Timestampable(on: 'create')]
+ #[ORM\Column(name: 'created', type: Types::DATETIME_IMMUTABLE)]
+ private ?DateTimeImmutable $created;
/**
- * @ORM\Column(name="updated", type="datetime")
+ * @ORM\Column(name="updated", type="datetime_immutable")
* @Gedmo\Timestampable(on="update")
*/
- private $updated;
+ #[Gedmo\Timestampable(on: 'update')]
+ #[ORM\Column(name: 'updated', type: Types::DATETIME_IMMUTABLE)]
+ private ?DateTimeImmutable $updated;
/**
- * @ORM\Column(type="datetime", nullable=true)
+ * @ORM\Column(type="datetime_immutable", nullable=true)
*/
- private $deletedAt;
+ #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
+ private ?DateTimeImmutable $deletedAt;
- public function getId()
+ public function getId(): ?int
{
return $this->id;
}
- public function setTitle($title)
+ public function setTitle(?string $title): void
{
$this->title = $title;
}
- public function getTitle()
+ public function getTitle(): ?string
{
return $this->title;
}
- public function getCreated()
+ public function getCreated(): ?DateTimeImmutable
{
return $this->created;
}
- public function getUpdated()
+ public function getUpdated(): ?DateTimeImmutable
{
return $this->updated;
}
- public function getDeletedAt(): ?Datetime
+ public function getDeletedAt(): ?DateTimeImmutable
{
return $this->deletedAt;
}
- public function setDeletedAt(?Datetime $deletedAt): void
+ public function setDeletedAt(?DateTimeImmutable $deletedAt): void
{
$this->deletedAt = $deletedAt;
}
@@ -409,9 +455,8 @@ and add an action to test how it works:
/**
* @Route("/posts", name="_demo_posts")
*/
-public function postsAction()
+public function postsAction(EntityManagerInterface $em): Response
{
- $em = $this->getDoctrine()->getManager();
$repository = $em->getRepository(App\Entity\BlogPost::class);
// create some posts in case if there aren't any
if (!$repository->find('hello_world')) {
@@ -463,7 +508,7 @@ doctrine_mongodb:
auto_mapping: true
mappings:
translatable:
- type: annotation # or attribute
+ type: attribute # or annotation or xml
alias: GedmoDocument
prefix: Gedmo\Translatable\Document
# make sure vendor library location is correct