Skip to content

Commit 7696b7c

Browse files
Fix bug create tag with same name multiple times
1 parent 29afa52 commit 7696b7c

File tree

2 files changed

+65
-29
lines changed

2 files changed

+65
-29
lines changed

Content/Infrastructure/Doctrine/TagFactory.php

+25-6
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,41 @@ public function create(array $tagNames): array
5252
// sort tags by the given names order
5353
$excerptTags = [];
5454
foreach ($tags as $tag) {
55-
$excerptTags[array_search($tag->getName(), $tagNames, true)] = $tag;
55+
$index = array_search($tag->getName(), $tagNames, true);
56+
$excerptTags[$index] = $tag;
57+
unset($tagNames[$index]);
5658
}
5759

58-
// create tags which not exist yet
59-
foreach ($tagNames as $key => $tagName) {
60-
if (isset($excerptTags[$key])) {
61-
continue;
60+
// check if a tag with the same name was yet persisted and use that instead of create one
61+
// this avoids a unique constraint error to create multiple tag with same name
62+
if (\count($tagNames)) {
63+
// we use here the unitOfWork instead of an own cache this avoid us listing for
64+
// flush, clear or deletion events and so we don't need to invalid an cache ourselves
65+
foreach ($this->entityManager->getUnitOfWork()->getScheduledEntityInsertions() as $object) {
66+
if (!$object instanceof TagInterface) {
67+
continue;
68+
}
69+
70+
$index = array_search($object->getName(), $tagNames, true);
71+
72+
if (false === $index) {
73+
continue;
74+
}
75+
76+
$excerptTags[$index] = $object;
77+
unset($tagNames[$index]);
6278
}
79+
}
6380

81+
// create missing tags which not exist yet
82+
foreach ($tagNames as $index => $tagName) {
6483
/** @var TagInterface $tag */
6584
$tag = $this->tagRepository->createNew();
6685
$tag->setName($tagName);
6786

6887
$this->entityManager->persist($tag);
6988

70-
$excerptTags[$key] = $tag;
89+
$excerptTags[$index] = $tag;
7190
}
7291

7392
return $excerptTags;

Tests/Functional/Content/Infrastructure/Doctrine/TagFactoryTest.php

+40-23
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,17 @@
2020

2121
class TagFactoryTest extends SuluTestCase
2222
{
23+
/**
24+
* @var TagFactoryInterface
25+
*/
26+
private $tagFactory;
27+
2328
protected function setUp(): void
2429
{
2530
self::bootKernel();
2631
self::purgeDatabase();
27-
}
28-
29-
/**
30-
* @param string[] $existTagNames
31-
*/
32-
protected function createTagFactory(array $existTagNames = []): TagFactoryInterface
33-
{
34-
/** @var TagRepositoryInterface $tagRepository */
35-
$tagRepository = self::$container->get('sulu.repository.tag');
36-
37-
foreach ($existTagNames as $existTagName) {
38-
$existTag = $tagRepository->createNew();
39-
$existTag->setName($existTagName);
40-
self::getEntityManager()->persist($existTag);
41-
}
42-
43-
if (\count($existTagNames)) {
44-
self::getEntityManager()->flush();
45-
self::getEntityManager()->clear();
46-
}
4732

48-
return self::$container->get('sulu_content.tag_factory');
33+
$this->tagFactory = self::$container->get('sulu_content.tag_factory');
4934
}
5035

5136
/**
@@ -56,19 +41,31 @@ protected function createTagFactory(array $existTagNames = []): TagFactoryInterf
5641
*/
5742
public function testCreate(array $tagNames, array $existTags): void
5843
{
59-
$tagFactory = $this->createTagFactory($existTags);
44+
$this->createTags($existTags);
45+
46+
$tags = $this->tagFactory->create($tagNames);
6047

6148
$this->assertSame(
6249
$tagNames,
6350
array_map(
6451
function (TagInterface $tag) {
6552
return $tag->getName();
6653
},
67-
$tagFactory->create($tagNames)
54+
$tags
6855
)
6956
);
7057
}
7158

59+
public function testCreateSameTagTwice(): void
60+
{
61+
$tags1 = $this->tagFactory->create(['Tag 1']);
62+
$tags2 = $this->tagFactory->create(['Tag 1']);
63+
64+
$this->assertSame($tags1, $tags2);
65+
66+
$this->getEntityManager()->flush();
67+
}
68+
7269
/**
7370
* @return \Generator<mixed[]>
7471
*/
@@ -114,4 +111,24 @@ public function dataProvider(): \Generator
114111
],
115112
];
116113
}
114+
115+
/**
116+
* @param string[] $existTagNames
117+
*/
118+
private function createTags(array $existTagNames = []): void
119+
{
120+
/** @var TagRepositoryInterface $tagRepository */
121+
$tagRepository = self::$container->get('sulu.repository.tag');
122+
123+
foreach ($existTagNames as $existTagName) {
124+
$existTag = $tagRepository->createNew();
125+
$existTag->setName($existTagName);
126+
self::getEntityManager()->persist($existTag);
127+
}
128+
129+
if (\count($existTagNames)) {
130+
self::getEntityManager()->flush();
131+
self::getEntityManager()->clear();
132+
}
133+
}
117134
}

0 commit comments

Comments
 (0)