diff options
author | Jeremy Benoist <jeremy.benoist@gmail.com> | 2016-09-25 11:26:15 +0200 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2016-09-25 12:03:49 +0200 |
commit | 401135852c6b25c8d5ab97beaefb02d1bd023ec9 (patch) | |
tree | 5922f4bd40af0ceb61db2c55755bc006f18410fb | |
parent | faa86e06ba3032fdb98f3c0f79c72e8581d3c96f (diff) | |
download | wallabag-401135852c6b25c8d5ab97beaefb02d1bd023ec9.tar.gz wallabag-401135852c6b25c8d5ab97beaefb02d1bd023ec9.tar.zst wallabag-401135852c6b25c8d5ab97beaefb02d1bd023ec9.zip |
Use scheduled entity insertions to avoid tag duplicate
Using `getScheduledEntityInsertions()` we can retrieve not yet flushed but already persisted entities and then avoid tags duplication on import.
7 files changed, 89 insertions, 7 deletions
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php index 5dd684f2..a65a21e8 100644 --- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php +++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php | |||
@@ -96,13 +96,24 @@ class ContentProxy | |||
96 | * | 96 | * |
97 | * @param Entry $entry | 97 | * @param Entry $entry |
98 | * @param array|string $tags An array of tag or a string coma separated of tag | 98 | * @param array|string $tags An array of tag or a string coma separated of tag |
99 | * @param array $entitiesReady Entities from the EntityManager which are persisted but not yet flushed | ||
100 | * It is mostly to fix duplicate tag on import | ||
101 | * @see http://stackoverflow.com/a/7879164/569101 | ||
99 | */ | 102 | */ |
100 | public function assignTagsToEntry(Entry $entry, $tags) | 103 | public function assignTagsToEntry(Entry $entry, $tags, array $entitiesReady = []) |
101 | { | 104 | { |
102 | if (!is_array($tags)) { | 105 | if (!is_array($tags)) { |
103 | $tags = explode(',', $tags); | 106 | $tags = explode(',', $tags); |
104 | } | 107 | } |
105 | 108 | ||
109 | // keeps only Tag entity from the "not yet flushed entities" | ||
110 | $tagsNotYetFlushed = []; | ||
111 | foreach ($entitiesReady as $entity) { | ||
112 | if ($entity instanceof Tag) { | ||
113 | $tagsNotYetFlushed[$entity->getLabel()] = $entity; | ||
114 | } | ||
115 | } | ||
116 | |||
106 | foreach ($tags as $label) { | 117 | foreach ($tags as $label) { |
107 | $label = trim($label); | 118 | $label = trim($label); |
108 | 119 | ||
@@ -111,11 +122,15 @@ class ContentProxy | |||
111 | continue; | 122 | continue; |
112 | } | 123 | } |
113 | 124 | ||
114 | $tagEntity = $this->tagRepository->findOneByLabel($label); | 125 | if (isset($tagsNotYetFlushed[$label])) { |
126 | $tagEntity = $tagsNotYetFlushed[$label]; | ||
127 | } else { | ||
128 | $tagEntity = $this->tagRepository->findOneByLabel($label); | ||
115 | 129 | ||
116 | if (is_null($tagEntity)) { | 130 | if (is_null($tagEntity)) { |
117 | $tagEntity = new Tag(); | 131 | $tagEntity = new Tag(); |
118 | $tagEntity->setLabel($label); | 132 | $tagEntity->setLabel($label); |
133 | } | ||
119 | } | 134 | } |
120 | 135 | ||
121 | // only add the tag on the entry if the relation doesn't exist | 136 | // only add the tag on the entry if the relation doesn't exist |
diff --git a/src/Wallabag/ImportBundle/Import/PocketImport.php b/src/Wallabag/ImportBundle/Import/PocketImport.php index e00eb44b..327e2500 100644 --- a/src/Wallabag/ImportBundle/Import/PocketImport.php +++ b/src/Wallabag/ImportBundle/Import/PocketImport.php | |||
@@ -227,7 +227,8 @@ class PocketImport extends AbstractImport | |||
227 | if (isset($importedEntry['tags']) && !empty($importedEntry['tags'])) { | 227 | if (isset($importedEntry['tags']) && !empty($importedEntry['tags'])) { |
228 | $this->contentProxy->assignTagsToEntry( | 228 | $this->contentProxy->assignTagsToEntry( |
229 | $entry, | 229 | $entry, |
230 | array_keys($importedEntry['tags']) | 230 | array_keys($importedEntry['tags']), |
231 | $this->em->getUnitOfWork()->getScheduledEntityInsertions() | ||
231 | ); | 232 | ); |
232 | } | 233 | } |
233 | 234 | ||
diff --git a/src/Wallabag/ImportBundle/Import/WallabagImport.php b/src/Wallabag/ImportBundle/Import/WallabagImport.php index 043bb0a2..3754e4a9 100644 --- a/src/Wallabag/ImportBundle/Import/WallabagImport.php +++ b/src/Wallabag/ImportBundle/Import/WallabagImport.php | |||
@@ -111,7 +111,8 @@ abstract class WallabagImport extends AbstractImport | |||
111 | if (array_key_exists('tags', $data)) { | 111 | if (array_key_exists('tags', $data)) { |
112 | $this->contentProxy->assignTagsToEntry( | 112 | $this->contentProxy->assignTagsToEntry( |
113 | $entry, | 113 | $entry, |
114 | $data['tags'] | 114 | $data['tags'], |
115 | $this->em->getUnitOfWork()->getScheduledEntityInsertions() | ||
115 | ); | 116 | ); |
116 | } | 117 | } |
117 | 118 | ||
diff --git a/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php b/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php index 7abb0737..5d772602 100644 --- a/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php +++ b/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php | |||
@@ -296,6 +296,29 @@ class ContentProxyTest extends \PHPUnit_Framework_TestCase | |||
296 | $this->assertEquals('tag2', $entry->getTags()[1]->getLabel()); | 296 | $this->assertEquals('tag2', $entry->getTags()[1]->getLabel()); |
297 | } | 297 | } |
298 | 298 | ||
299 | public function testAssignTagsNotFlushed() | ||
300 | { | ||
301 | $graby = $this->getMockBuilder('Graby\Graby') | ||
302 | ->disableOriginalConstructor() | ||
303 | ->getMock(); | ||
304 | |||
305 | $tagRepo = $this->getTagRepositoryMock(); | ||
306 | $tagRepo->expects($this->never()) | ||
307 | ->method('__call'); | ||
308 | |||
309 | $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger()); | ||
310 | |||
311 | $tagEntity = new Tag(); | ||
312 | $tagEntity->setLabel('tag1'); | ||
313 | |||
314 | $entry = new Entry(new User()); | ||
315 | |||
316 | $proxy->assignTagsToEntry($entry, 'tag1', [$tagEntity]); | ||
317 | |||
318 | $this->assertCount(1, $entry->getTags()); | ||
319 | $this->assertEquals('tag1', $entry->getTags()[0]->getLabel()); | ||
320 | } | ||
321 | |||
299 | private function getTaggerMock() | 322 | private function getTaggerMock() |
300 | { | 323 | { |
301 | return $this->getMockBuilder('Wallabag\CoreBundle\Helper\RuleBasedTagger') | 324 | return $this->getMockBuilder('Wallabag\CoreBundle\Helper\RuleBasedTagger') |
diff --git a/tests/Wallabag/ImportBundle/Import/PocketImportTest.php b/tests/Wallabag/ImportBundle/Import/PocketImportTest.php index 952521a2..9ec7935c 100644 --- a/tests/Wallabag/ImportBundle/Import/PocketImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/PocketImportTest.php | |||
@@ -41,6 +41,20 @@ class PocketImportTest extends \PHPUnit_Framework_TestCase | |||
41 | ->disableOriginalConstructor() | 41 | ->disableOriginalConstructor() |
42 | ->getMock(); | 42 | ->getMock(); |
43 | 43 | ||
44 | $this->uow = $this->getMockBuilder('Doctrine\ORM\UnitOfWork') | ||
45 | ->disableOriginalConstructor() | ||
46 | ->getMock(); | ||
47 | |||
48 | $this->em | ||
49 | ->expects($this->any()) | ||
50 | ->method('getUnitOfWork') | ||
51 | ->willReturn($this->uow); | ||
52 | |||
53 | $this->uow | ||
54 | ->expects($this->any()) | ||
55 | ->method('getScheduledEntityInsertions') | ||
56 | ->willReturn([]); | ||
57 | |||
44 | $pocket = new PocketImport( | 58 | $pocket = new PocketImport( |
45 | $this->em, | 59 | $this->em, |
46 | $this->contentProxy | 60 | $this->contentProxy |
diff --git a/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php b/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php index 5ab4ad00..82dc4c7e 100644 --- a/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php | |||
@@ -26,6 +26,20 @@ class WallabagV1ImportTest extends \PHPUnit_Framework_TestCase | |||
26 | ->disableOriginalConstructor() | 26 | ->disableOriginalConstructor() |
27 | ->getMock(); | 27 | ->getMock(); |
28 | 28 | ||
29 | $this->uow = $this->getMockBuilder('Doctrine\ORM\UnitOfWork') | ||
30 | ->disableOriginalConstructor() | ||
31 | ->getMock(); | ||
32 | |||
33 | $this->em | ||
34 | ->expects($this->any()) | ||
35 | ->method('getUnitOfWork') | ||
36 | ->willReturn($this->uow); | ||
37 | |||
38 | $this->uow | ||
39 | ->expects($this->any()) | ||
40 | ->method('getScheduledEntityInsertions') | ||
41 | ->willReturn([]); | ||
42 | |||
29 | $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') | 43 | $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') |
30 | ->disableOriginalConstructor() | 44 | ->disableOriginalConstructor() |
31 | ->getMock(); | 45 | ->getMock(); |
diff --git a/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php b/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php index 12bd6bdd..bea89efb 100644 --- a/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php | |||
@@ -26,6 +26,20 @@ class WallabagV2ImportTest extends \PHPUnit_Framework_TestCase | |||
26 | ->disableOriginalConstructor() | 26 | ->disableOriginalConstructor() |
27 | ->getMock(); | 27 | ->getMock(); |
28 | 28 | ||
29 | $this->uow = $this->getMockBuilder('Doctrine\ORM\UnitOfWork') | ||
30 | ->disableOriginalConstructor() | ||
31 | ->getMock(); | ||
32 | |||
33 | $this->em | ||
34 | ->expects($this->any()) | ||
35 | ->method('getUnitOfWork') | ||
36 | ->willReturn($this->uow); | ||
37 | |||
38 | $this->uow | ||
39 | ->expects($this->any()) | ||
40 | ->method('getScheduledEntityInsertions') | ||
41 | ->willReturn([]); | ||
42 | |||
29 | $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') | 43 | $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') |
30 | ->disableOriginalConstructor() | 44 | ->disableOriginalConstructor() |
31 | ->getMock(); | 45 | ->getMock(); |