diff options
7 files changed, 147 insertions, 42 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/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml index f57db303..a066c8e3 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml | |||
@@ -1,36 +1,36 @@ | |||
1 | # settings_changed: Configuration updated | 1 | settings_changed: 'Konfiguration aktualisiert' |
2 | download_pictures: Bilder auf den Server herunterladen | 2 | download_pictures: 'Bilder auf den Server herunterladen' |
3 | carrot: Teilen zu Carrot aktivieren | 3 | carrot: 'Teilen zu Carrot aktivieren' |
4 | diaspora_url: Diaspora-URL, sofern der Service aktiviert ist | 4 | diaspora_url: 'Diaspora-URL, sofern der Service aktiviert ist' |
5 | export_epub: ePUB-Export aktivieren | 5 | export_epub: 'ePUB-Export aktivieren' |
6 | export_mobi: mobi-Export aktivieren | 6 | export_mobi: 'mobi-Export aktivieren' |
7 | export_pdf: PDF-Export aktivieren | 7 | export_pdf: 'PDF-Export aktivieren' |
8 | export_csv: CSV-Export aktivieren | 8 | export_csv: 'CSV-Export aktivieren' |
9 | export_json: JSON-Export aktivieren | 9 | export_json: 'JSON-Export aktivieren' |
10 | export_txt: TXT-Export aktivieren | 10 | export_txt: 'TXT-Export aktivieren' |
11 | export_xml: XML-Export aktivieren | 11 | export_xml: 'XML-Export aktivieren' |
12 | import_with_rabbitmq: Aktiviere RabbitMQ, um Artikel asynchron zu importieren | 12 | import_with_rabbitmq: 'Aktiviere RabbitMQ, um Artikel asynchron zu importieren' |
13 | import_with_redis: Aktiviere Redis, um Artikel asynchron zu importieren | 13 | import_with_redis: 'Aktiviere Redis, um Artikel asynchron zu importieren' |
14 | shaarli_url: Shaarli-URL, sofern der Service aktiviert ist | 14 | shaarli_url: 'Shaarli-URL, sofern der Service aktiviert ist' |
15 | share_diaspora: Teilen zu Diaspora aktiveren | 15 | share_diaspora: 'Teilen zu Diaspora aktiveren' |
16 | share_mail: Teilen via E-Mail aktiveren | 16 | share_mail: 'Teilen via E-Mail aktiveren' |
17 | share_shaarli: Teilen zu Shaarli aktiveren | 17 | share_shaarli: 'Teilen zu Shaarli aktiveren' |
18 | share_scuttle: Teilen zu Scuttle aktiveren | 18 | share_twitter: 'Teilen zu Twitter aktiveren' |
19 | share_twitter: Teilen zu Twitter aktiveren | 19 | share_unmark: 'Teilen zu Unmark.it aktiveren' |
20 | share_unmark: Teilen zu Unmark.it aktiveren | 20 | show_printlink: 'Link anzeigen, um den Inhalt auszudrucken' |
21 | show_printlink: Link anzeigen, um den Inhalt auszudrucken | 21 | wallabag_support_url: 'Support-URL für wallabag' |
22 | wallabag_support_url: Support-URL für wallabag | 22 | wallabag_url: 'URL von *deiner* wallabag-Instanz' |
23 | entry: "Artikel" | 23 | entry: 'Artikel' |
24 | export: "Export" | 24 | export: 'Export' |
25 | import: "Import" | 25 | import: 'Import' |
26 | misc: "Verschiedenes" | 26 | misc: 'Verschiedenes' |
27 | modify_settings: "Übernehmen" | 27 | modify_settings: 'Übernehmen' |
28 | piwik_host: Host deiner Webseite in Piwik (ohne http:// oder https://) | 28 | piwik_host: 'Host deiner Webseite in Piwik (ohne http:// oder https://)' |
29 | piwik_site_id: ID deiner Webseite in Piwik | 29 | piwik_site_id: 'ID deiner Webseite in Piwik' |
30 | piwik_enabled: Piwik aktivieren | 30 | piwik_enabled: 'Piwik aktivieren' |
31 | demo_mode_enabled: "Test-Modus aktivieren? (nur für die öffentliche wallabag-Demo genutzt)" | 31 | demo_mode_enabled: 'Test-Modus aktivieren? (nur für die öffentliche wallabag-Demo genutzt)' |
32 | demo_mode_username: "Test-Benutzer" | 32 | demo_mode_username: 'Test-Benutzer' |
33 | share_public: Erlaube eine öffentliche URL für Einträge | 33 | share_public: 'Erlaube eine öffentliche URL für Einträge' |
34 | # download_images_enabled: Download images locally | 34 | download_images_enabled: 'Bilder lokal herunterladen' |
35 | # restricted_access: Enable authentication for websites with paywall | 35 | restricted_access: 'Authentifizierung für Webseiten mit Paywall aktivieren' |
36 | # api_user_registration: Enable user to be registered using the API | 36 | api_user_registration: 'Registrierung eines Benutzers über die API ermöglichen' |
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()); |