File: FlushEventTest.php

package info (click to toggle)
doctrine 3.5.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 11,552 kB
  • sloc: php: 108,302; xml: 1,340; makefile: 35; sh: 14
file content (137 lines) | stat: -rw-r--r-- 3,963 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional;

use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Events;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\OrmFunctionalTestCase;
use PHPUnit\Framework\Attributes\Group;

/**
 * FlushEventTest
 */
class FlushEventTest extends OrmFunctionalTestCase
{
    protected function setUp(): void
    {
        $this->useModelSet('cms');

        parent::setUp();
    }

    public function testPersistNewEntitiesOnPreFlush(): void
    {
        $this->_em->getEventManager()->addEventListener(Events::onFlush, new OnFlushListener());

        $user           = new CmsUser();
        $user->username = 'romanb';
        $user->name     = 'Roman';
        $user->status   = 'Dev';

        $this->_em->persist($user);

        self::assertEquals(0, $user->phonenumbers->count());

        $this->_em->flush();

        self::assertEquals(1, $user->phonenumbers->count());
        self::assertTrue($this->_em->contains($user->phonenumbers->get(0)));
        self::assertSame($user->phonenumbers->get(0)->getUser(), $user);

        self::assertFalse($user->phonenumbers->isDirty());

        // Can be used together with SQL Logging to check that a subsequent flush has
        // nothing to do. This proofs the correctness of the changes that happened in onFlush.
        //echo "SECOND FLUSH";
        //$this->_em->flush();
    }

    #[Group('DDC-2173')]
    public function testPreAndOnFlushCalledAlways(): void
    {
        $listener = new OnFlushCalledListener();
        $this->_em->getEventManager()->addEventListener(Events::onFlush, $listener);
        $this->_em->getEventManager()->addEventListener(Events::preFlush, $listener);
        $this->_em->getEventManager()->addEventListener(Events::postFlush, $listener);

        $this->_em->flush();

        self::assertEquals(1, $listener->preFlush);
        self::assertEquals(1, $listener->onFlush);

        $this->_em->flush();

        self::assertEquals(2, $listener->preFlush);
        self::assertEquals(2, $listener->onFlush);
    }
}

class OnFlushListener
{
    public function onFlush(OnFlushEventArgs $args): void
    {
        //echo "---preFlush".PHP_EOL;

        $em  = $args->getObjectManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            if ($entity instanceof CmsUser) {
                // Adds a phonenumber to every newly persisted CmsUser ...

                $phone              = new CmsPhonenumber();
                $phone->phonenumber = 12345;
                // Update object model
                $entity->addPhonenumber($phone);
                // Invoke regular persist call
                $em->persist($phone);
                // Explicitly calculate the changeset since onFlush is raised
                // after changeset calculation!
                $uow->computeChangeSet($em->getClassMetadata($phone::class), $phone);

                // Take a snapshot because the UoW wont do this for us, because
                // the UoW did not visit this collection.
                // Alternatively we could provide an ->addVisitedCollection() method
                // on the UoW.
                $entity->getPhonenumbers()->takeSnapshot();
            }

            /*foreach ($uow->getEntityChangeSet($entity) as $field => $change) {
                list ($old, $new) = $change;

                var_dump($old);
            }*/
        }
    }
}

class OnFlushCalledListener
{
    /** @var int */
    public $preFlush = 0;

    /** @var int */
    public $onFlush = 0;

    /** @var int */
    public $postFlush = 0;

    public function preFlush($args): void
    {
        $this->preFlush++;
    }

    public function onFlush($args): void
    {
        $this->onFlush++;
    }

    public function postFlush($args): void
    {
        $this->postFlush++;
    }
}