diff options
author | Jérémy Benoist <j0k3r@users.noreply.github.com> | 2017-09-03 20:25:15 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-03 20:25:15 +0200 |
commit | 3af5d41759c13420faa6f426491f1e95e5754908 (patch) | |
tree | 7ae4ccdc515838cbb5a879e4308a3a742a4de1cf | |
parent | 9c4d1eb56a6bdd3cdeb5bed3d58be18395a5134b (diff) | |
parent | 7b4f66881d694c948aca9372da6362b8873de6bb (diff) | |
download | wallabag-3af5d41759c13420faa6f426491f1e95e5754908.tar.gz wallabag-3af5d41759c13420faa6f426491f1e95e5754908.tar.zst wallabag-3af5d41759c13420faa6f426491f1e95e5754908.zip |
Merge pull request #3139 from Kdecherf/2502-tag-case
Ignore tag's case
6 files changed, 111 insertions, 6 deletions
diff --git a/app/DoctrineMigrations/Version20170719231144.php b/app/DoctrineMigrations/Version20170719231144.php new file mode 100644 index 00000000..0f5fa75a --- /dev/null +++ b/app/DoctrineMigrations/Version20170719231144.php | |||
@@ -0,0 +1,103 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Application\Migrations; | ||
4 | |||
5 | use Doctrine\DBAL\Migrations\AbstractMigration; | ||
6 | use Doctrine\DBAL\Schema\Schema; | ||
7 | use Symfony\Component\DependencyInjection\ContainerAwareInterface; | ||
8 | use Symfony\Component\DependencyInjection\ContainerInterface; | ||
9 | |||
10 | /** | ||
11 | * Changed tags to lowercase. | ||
12 | */ | ||
13 | class Version20170719231144 extends AbstractMigration implements ContainerAwareInterface | ||
14 | { | ||
15 | /** | ||
16 | * @var ContainerInterface | ||
17 | */ | ||
18 | private $container; | ||
19 | |||
20 | public function setContainer(ContainerInterface $container = null) | ||
21 | { | ||
22 | $this->container = $container; | ||
23 | } | ||
24 | |||
25 | /** | ||
26 | * @param Schema $schema | ||
27 | */ | ||
28 | public function up(Schema $schema) | ||
29 | { | ||
30 | $this->skipIf($this->connection->getDatabasePlatform()->getName() === 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); | ||
31 | |||
32 | // Find tags which need to be merged | ||
33 | $dupTags = $this->connection->query(' | ||
34 | SELECT LOWER(label) | ||
35 | FROM ' . $this->getTable('tag') . ' | ||
36 | GROUP BY LOWER(label) | ||
37 | HAVING COUNT(*) > 1' | ||
38 | ); | ||
39 | $dupTags->execute(); | ||
40 | |||
41 | foreach ($dupTags->fetchAll() as $duplicates) { | ||
42 | $label = $duplicates['LOWER(label)']; | ||
43 | |||
44 | // Retrieve all duplicate tags for a given tag | ||
45 | $tags = $this->connection->query(' | ||
46 | SELECT id | ||
47 | FROM ' . $this->getTable('tag') . " | ||
48 | WHERE LOWER(label) = '" . $label . "' | ||
49 | ORDER BY id ASC" | ||
50 | ); | ||
51 | $tags->execute(); | ||
52 | |||
53 | $first = true; | ||
54 | $newId = null; | ||
55 | $ids = []; | ||
56 | |||
57 | foreach ($tags->fetchAll() as $tag) { | ||
58 | // Ignore the first tag as we use it as the new reference tag | ||
59 | if ($first) { | ||
60 | $first = false; | ||
61 | $newId = $tag['id']; | ||
62 | } else { | ||
63 | $ids[] = $tag['id']; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | // Just in case... | ||
68 | if (count($ids) > 0) { | ||
69 | // Merge tags | ||
70 | $this->addSql(' | ||
71 | UPDATE ' . $this->getTable('entry_tag') . ' | ||
72 | SET tag_id = ' . $newId . ' | ||
73 | WHERE tag_id IN (' . implode(',', $ids) . ')' | ||
74 | ); | ||
75 | |||
76 | // Delete unused tags | ||
77 | $this->addSql(' | ||
78 | DELETE FROM ' . $this->getTable('tag') . ' | ||
79 | WHERE id IN (' . implode(',', $ids) . ')' | ||
80 | ); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | // Iterate over all tags to lowercase them | ||
85 | $this->addSql(' | ||
86 | UPDATE ' . $this->getTable('tag') . ' | ||
87 | SET label = LOWER(label)' | ||
88 | ); | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * @param Schema $schema | ||
93 | */ | ||
94 | public function down(Schema $schema) | ||
95 | { | ||
96 | throw new SkipMigrationException('Too complex ...'); | ||
97 | } | ||
98 | |||
99 | private function getTable($tableName) | ||
100 | { | ||
101 | return $this->container->getParameter('database_table_prefix') . $tableName; | ||
102 | } | ||
103 | } | ||
diff --git a/src/Wallabag/CoreBundle/Entity/Tag.php b/src/Wallabag/CoreBundle/Entity/Tag.php index c19023af..a6dc8c50 100644 --- a/src/Wallabag/CoreBundle/Entity/Tag.php +++ b/src/Wallabag/CoreBundle/Entity/Tag.php | |||
@@ -78,7 +78,7 @@ class Tag | |||
78 | */ | 78 | */ |
79 | public function setLabel($label) | 79 | public function setLabel($label) |
80 | { | 80 | { |
81 | $this->label = $label; | 81 | $this->label = mb_convert_case($label, MB_CASE_LOWER); |
82 | 82 | ||
83 | return $this; | 83 | return $this; |
84 | } | 84 | } |
diff --git a/src/Wallabag/CoreBundle/Helper/TagsAssigner.php b/src/Wallabag/CoreBundle/Helper/TagsAssigner.php index a2fb0b9a..0bfe5c57 100644 --- a/src/Wallabag/CoreBundle/Helper/TagsAssigner.php +++ b/src/Wallabag/CoreBundle/Helper/TagsAssigner.php | |||
@@ -45,7 +45,7 @@ class TagsAssigner | |||
45 | } | 45 | } |
46 | 46 | ||
47 | foreach ($tags as $label) { | 47 | foreach ($tags as $label) { |
48 | $label = trim($label); | 48 | $label = trim(mb_convert_case($label, MB_CASE_LOWER)); |
49 | 49 | ||
50 | // avoid empty tag | 50 | // avoid empty tag |
51 | if (0 === strlen($label)) { | 51 | if (0 === strlen($label)) { |
diff --git a/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php index be25a8b5..5a973a7e 100644 --- a/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php | |||
@@ -9,6 +9,7 @@ use Wallabag\CoreBundle\Entity\Tag; | |||
9 | class TagControllerTest extends WallabagCoreTestCase | 9 | class TagControllerTest extends WallabagCoreTestCase |
10 | { | 10 | { |
11 | public $tagName = 'opensource'; | 11 | public $tagName = 'opensource'; |
12 | public $caseTagName = 'OpenSource'; | ||
12 | 13 | ||
13 | public function testList() | 14 | public function testList() |
14 | { | 15 | { |
@@ -36,7 +37,7 @@ class TagControllerTest extends WallabagCoreTestCase | |||
36 | $form = $crawler->filter('form[name=tag]')->form(); | 37 | $form = $crawler->filter('form[name=tag]')->form(); |
37 | 38 | ||
38 | $data = [ | 39 | $data = [ |
39 | 'tag[label]' => $this->tagName, | 40 | 'tag[label]' => $this->caseTagName, |
40 | ]; | 41 | ]; |
41 | 42 | ||
42 | $client->submit($form, $data); | 43 | $client->submit($form, $data); |
@@ -45,6 +46,7 @@ class TagControllerTest extends WallabagCoreTestCase | |||
45 | // be sure to reload the entry | 46 | // be sure to reload the entry |
46 | $entry = $this->getEntityManager()->getRepository(Entry::class)->find($entry->getId()); | 47 | $entry = $this->getEntityManager()->getRepository(Entry::class)->find($entry->getId()); |
47 | $this->assertCount(1, $entry->getTags()); | 48 | $this->assertCount(1, $entry->getTags()); |
49 | $this->assertContains($this->tagName, $entry->getTags()); | ||
48 | 50 | ||
49 | // tag already exists and already assigned | 51 | // tag already exists and already assigned |
50 | $client->submit($form, $data); | 52 | $client->submit($form, $data); |
@@ -80,7 +82,7 @@ class TagControllerTest extends WallabagCoreTestCase | |||
80 | $form = $crawler->filter('form[name=tag]')->form(); | 82 | $form = $crawler->filter('form[name=tag]')->form(); |
81 | 83 | ||
82 | $data = [ | 84 | $data = [ |
83 | 'tag[label]' => 'foo2, bar2', | 85 | 'tag[label]' => 'foo2, Bar2', |
84 | ]; | 86 | ]; |
85 | 87 | ||
86 | $client->submit($form, $data); | 88 | $client->submit($form, $data); |
diff --git a/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php b/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php index c307f96c..9bb59766 100644 --- a/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php | |||
@@ -125,7 +125,7 @@ class PinboardControllerTest extends WallabagCoreTestCase | |||
125 | $tags = $content->getTags(); | 125 | $tags = $content->getTags(); |
126 | $this->assertContains('foot', $tags, 'It includes the "foot" tag'); | 126 | $this->assertContains('foot', $tags, 'It includes the "foot" tag'); |
127 | $this->assertContains('varnish', $tags, 'It includes the "varnish" tag'); | 127 | $this->assertContains('varnish', $tags, 'It includes the "varnish" tag'); |
128 | $this->assertContains('PHP', $tags, 'It includes the "PHP" tag'); | 128 | $this->assertContains('php', $tags, 'It includes the "php" tag'); |
129 | $this->assertSame(3, count($tags)); | 129 | $this->assertSame(3, count($tags)); |
130 | 130 | ||
131 | $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt()); | 131 | $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt()); |
diff --git a/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php b/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php index 25625c35..4bc982e0 100644 --- a/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php | |||
@@ -125,7 +125,7 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase | |||
125 | 125 | ||
126 | $tags = $content->getTags(); | 126 | $tags = $content->getTags(); |
127 | $this->assertContains('foot', $tags, 'It includes the "foot" tag'); | 127 | $this->assertContains('foot', $tags, 'It includes the "foot" tag'); |
128 | $this->assertContains('Framabag', $tags, 'It includes the "Framabag" tag'); | 128 | $this->assertContains('framabag', $tags, 'It includes the "framabag" tag'); |
129 | $this->assertSame(2, count($tags)); | 129 | $this->assertSame(2, count($tags)); |
130 | 130 | ||
131 | $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt()); | 131 | $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt()); |