Skip to content

Commit 0d6d6aa

Browse files
feat: new workflow for cases where the collection has already started and there are no diffs
1 parent eeca602 commit 0d6d6aa

3 files changed

Lines changed: 69 additions & 4 deletions

File tree

app/Audit/AuditEventListener.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,10 @@ private function auditCollection($subject, $uow, string $eventType): array
177177
$payload = ['collection' => $subject];
178178

179179
if ($eventType === IAuditStrategy::EVENT_COLLECTION_MANYTOMANY_DELETE
180-
&& !$subject->isInitialized() ) {
180+
&& (
181+
!$subject->isInitialized()
182+
|| ($subject->isInitialized() && count($subject->getDeleteDiff()) === 0)
183+
)) {
181184
if ($this->em instanceof EntityManagerInterface) {
182185
$payload['deleted_ids'] = $this->fetchManyToManyIds($subject, $this->em);
183186
}

app/Audit/AuditLogOtlpStrategy.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,16 @@ private function buildAuditLogData($entity, $subject, array $change_set, string
189189
$data['audit.collection_type'] = $this->getCollectionType($collection);
190190
if (!empty($change_set['deleted_ids'])) {
191191
$data['audit.collection_count'] = count($change_set['deleted_ids']);
192-
$data['audit.collection_current_count'] = 0;
193-
$data['audit.collection_snapshot_count'] = 0;
194-
$data['audit.collection_is_dirty'] = 'true';
192+
if ($collection->isInitialized()) {
193+
$changes = $this->getCollectionChanges($collection, $change_set);
194+
$data['audit.collection_current_count'] = $changes['current_count'];
195+
$data['audit.collection_snapshot_count'] = $changes['snapshot_count'];
196+
$data['audit.collection_is_dirty'] = $changes['is_dirty'] ? 'true' : 'false';
197+
} else {
198+
$data['audit.collection_current_count'] = 0;
199+
$data['audit.collection_snapshot_count'] = 0;
200+
$data['audit.collection_is_dirty'] = 'true';
201+
}
195202
} elseif ($collection->isInitialized()) {
196203
$data['audit.collection_count'] = count($collection);
197204
$changes = $this->getCollectionChanges($collection, $change_set);

tests/OpenTelemetry/Formatters/AuditEventListenerTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,59 @@ public function testFetchManyToManyIdsExecutesQuery(): void
108108

109109
$this->assertSame([10, 11], $result);
110110
}
111+
112+
public function testAuditCollectionDeleteInitializedWithoutDiffUsesJoinTableQuery(): void
113+
{
114+
$listener = new AuditEventListener();
115+
$owner = new \stdClass();
116+
117+
$mapping = ManyToManyOwningSideMapping::fromMappingArrayAndNamingStrategy([
118+
'fieldName' => 'tags',
119+
'sourceEntity' => \stdClass::class,
120+
'targetEntity' => \stdClass::class,
121+
'isOwningSide' => true,
122+
'joinTable' => [
123+
'name' => 'owner_tags',
124+
'joinColumns' => [['name' => 'owner_id', 'referencedColumnName' => 'id']],
125+
'inverseJoinColumns' => [['name' => 'tag_id', 'referencedColumnName' => 'id']],
126+
],
127+
], new DefaultNamingStrategy());
128+
129+
$em = $this->createMock(EntityManagerInterface::class);
130+
$meta = new ClassMetadata(\stdClass::class);
131+
$collection = new PersistentCollection($em, $meta, new ArrayCollection());
132+
$collection->setOwner($owner, $mapping);
133+
$collection->takeSnapshot();
134+
135+
$ownerMeta = $this->getMockBuilder(ClassMetadata::class)
136+
->disableOriginalConstructor()
137+
->getMock();
138+
$ownerMeta->method('getIdentifierValues')->with($owner)->willReturn(['id' => 123]);
139+
140+
$conn = $this->getMockBuilder(Connection::class)
141+
->disableOriginalConstructor()
142+
->getMock();
143+
$conn->method('fetchFirstColumn')->willReturn(['10', '11']);
144+
145+
$em->method('getConnection')->willReturn($conn);
146+
$em->method('getClassMetadata')->with(get_class($owner))->willReturn($ownerMeta);
147+
148+
$emProp = new \ReflectionProperty(AuditEventListener::class, 'em');
149+
$emProp->setAccessible(true);
150+
$emProp->setValue($listener, $em);
151+
152+
$method = new \ReflectionMethod(AuditEventListener::class, 'auditCollection');
153+
$method->setAccessible(true);
154+
155+
[$subject, $payload, $eventType] = $method->invoke(
156+
$listener,
157+
$collection,
158+
new \stdClass(),
159+
IAuditStrategy::EVENT_COLLECTION_MANYTOMANY_DELETE
160+
);
161+
162+
$this->assertSame($owner, $subject);
163+
$this->assertSame([10, 11], $payload['deleted_ids']);
164+
$this->assertSame(IAuditStrategy::EVENT_COLLECTION_MANYTOMANY_DELETE, $eventType);
165+
}
111166
}

0 commit comments

Comments
 (0)