66
77use Arxy \FilesBundle \ManagerInterface ;
88use Arxy \FilesBundle \Model \File ;
9- use Closure ;
109use Doctrine \Common \Util \ClassUtils ;
10+ use Doctrine \DBAL \Event \TransactionCommitEventArgs ;
11+ use Doctrine \DBAL \Event \TransactionRollBackEventArgs ;
1112use Doctrine \ORM \EntityManagerInterface ;
1213use Doctrine \ORM \Event \LifecycleEventArgs ;
14+ use Doctrine \ORM \Event \OnClearEventArgs ;
1315use ReflectionObject ;
1416
1517final class DoctrineORMListener
1618{
1719 private ManagerInterface $ manager ;
20+ /** @var class-string<File> */
1821 private string $ class ;
19- private Closure $ move ;
20- private Closure $ remove ;
22+ private array $ pendingMove = [] ;
23+ private array $ pendingRemove = [] ;
2124
2225 public function __construct (ManagerInterface $ manager )
2326 {
2427 $ this ->class = $ manager ->getClass ();
2528 $ this ->manager = $ manager ;
26-
27- $ this ->move = static function (File $ file ) use ($ manager ): void {
28- $ manager ->moveFile ($ file );
29- };
30- $ this ->remove = static function (File $ file ) use ($ manager ): void {
31- $ manager ->remove ($ file );
32- };
3329 }
3430
3531 public function postPersist (LifecycleEventArgs $ eventArgs ): void
3632 {
3733 $ entity = $ eventArgs ->getEntity ();
3834 $ entityManager = $ eventArgs ->getEntityManager ();
3935 if ($ this ->supports ($ entity )) {
40- ($ this ->move )($ entity );
36+ $ this ->pendingMove [] = $ entity ;
37+ }
38+ foreach ($ this ->handleEmbeddable ($ entityManager , $ entity ) as $ file ) {
39+ $ this ->pendingMove [] = $ file ;
4140 }
42- $ this ->handleEmbeddable ($ entityManager , $ entity , $ this ->move );
4341 }
4442
4543 public function postRemove (LifecycleEventArgs $ eventArgs ): void
@@ -48,26 +46,63 @@ public function postRemove(LifecycleEventArgs $eventArgs): void
4846 $ entityManager = $ eventArgs ->getEntityManager ();
4947
5048 if ($ this ->supports ($ entity )) {
51- ($ this ->remove )($ entity );
49+ $ this ->pendingRemove [] = $ entity ;
50+ }
51+ foreach ($ this ->handleEmbeddable ($ entityManager , $ entity ) as $ file ) {
52+ $ this ->pendingRemove [] = $ file ;
53+ }
54+ }
55+
56+ public function onTransactionCommit (TransactionCommitEventArgs $ eventArgs ): void
57+ {
58+ if ($ eventArgs ->getConnection ()->isTransactionActive ()) {
59+ return ;
60+ }
61+
62+ $ pendingMove = $ this ->pendingMove ;
63+ foreach ($ pendingMove as $ file ) {
64+ $ this ->manager ->moveFile ($ file );
65+ }
66+
67+ $ pendingRemove = $ this ->pendingRemove ;
68+ foreach ($ pendingRemove as $ file ) {
69+ $ this ->manager ->remove ($ file );
5270 }
53- $ this ->handleEmbeddable ($ entityManager , $ entity , $ this ->remove );
71+
72+ $ this ->clearPending ();
73+ }
74+
75+ public function onTransactionRollBack (TransactionRollBackEventArgs $ eventArgs ): void
76+ {
77+ if ($ eventArgs ->getConnection ()->isTransactionActive ()) {
78+ return ;
79+ }
80+
81+ $ this ->clearPending ();
5482 }
5583
56- public function onClear (): void
84+ private function clearPending (): void
5785 {
86+ $ this ->pendingMove = [];
87+ $ this ->pendingRemove = [];
88+ }
89+
90+ public function onClear (OnClearEventArgs $ eventArgs ): void
91+ {
92+ if ($ eventArgs ->getEntityManager ()->getConnection ()->isTransactionActive ()) {
93+ return ;
94+ }
5895 $ this ->manager ->clear ();
96+ $ this ->clearPending ();
5997 }
6098
6199 private function supports (object $ entity ): bool
62100 {
63101 return $ entity instanceof $ this ->class ;
64102 }
65103
66- private function handleEmbeddable (
67- EntityManagerInterface $ entityManager ,
68- object $ entity ,
69- Closure $ action
70- ): void {
104+ private function handleEmbeddable (EntityManagerInterface $ entityManager , object $ entity ): iterable
105+ {
71106 $ classMetadata = $ entityManager ->getClassMetadata (ClassUtils::getClass ($ entity ));
72107
73108 foreach ($ classMetadata ->embeddedClasses as $ property => $ embeddedClass ) {
@@ -84,7 +119,7 @@ private function handleEmbeddable(
84119 if ($ file === null ) {
85120 continue ;
86121 }
87- $ action ( $ file) ;
122+ yield $ file ;
88123 }
89124 }
90125}
0 commit comments