diff options
author | Jeremy Benoist <j0k3r@users.noreply.github.com> | 2016-10-24 11:57:51 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-24 11:57:51 +0200 |
commit | 9313ea9d440e3f93a6bb2d8c0fb6717364cd27f5 (patch) | |
tree | 659842576e853a536c67e7c74139a73853b6caf2 | |
parent | a1c18418288a9521c980c96fd5defffc757a81c6 (diff) | |
parent | f623516e107c8146f87d815f033cecb5d812466a (diff) | |
download | wallabag-9313ea9d440e3f93a6bb2d8c0fb6717364cd27f5.tar.gz wallabag-9313ea9d440e3f93a6bb2d8c0fb6717364cd27f5.tar.zst wallabag-9313ea9d440e3f93a6bb2d8c0fb6717364cd27f5.zip |
Merge pull request #2401 from wallabag/reset-account
Reset account
39 files changed, 717 insertions, 63 deletions
diff --git a/app/DoctrineMigrations/Version20160410190541.php b/app/DoctrineMigrations/Version20160410190541.php index 4014857b..c41b0465 100644 --- a/app/DoctrineMigrations/Version20160410190541.php +++ b/app/DoctrineMigrations/Version20160410190541.php | |||
@@ -29,8 +29,12 @@ class Version20160410190541 extends AbstractMigration implements ContainerAwareI | |||
29 | */ | 29 | */ |
30 | public function up(Schema $schema) | 30 | public function up(Schema $schema) |
31 | { | 31 | { |
32 | $this->addSql('ALTER TABLE `'.$this->getTable('entry').'` ADD `uuid` LONGTEXT DEFAULT NULL'); | 32 | if ($this->connection->getDatabasePlatform()->getName() == 'postgresql') { |
33 | $this->addSql("INSERT INTO `".$this->getTable('craue_config_setting')."` (`name`, `value`, `section`) VALUES ('share_public', '1', 'entry')"); | 33 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' ADD uuid UUID DEFAULT NULL'); |
34 | } else { | ||
35 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' ADD uuid LONGTEXT DEFAULT NULL'); | ||
36 | } | ||
37 | $this->addSql("INSERT INTO ".$this->getTable('craue_config_setting')." (name, value, section) VALUES ('share_public', '1', 'entry')"); | ||
34 | } | 38 | } |
35 | 39 | ||
36 | /** | 40 | /** |
@@ -40,7 +44,7 @@ class Version20160410190541 extends AbstractMigration implements ContainerAwareI | |||
40 | { | 44 | { |
41 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'sqlite', 'This down migration can\'t be executed on SQLite databases, because SQLite don\'t support DROP COLUMN.'); | 45 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'sqlite', 'This down migration can\'t be executed on SQLite databases, because SQLite don\'t support DROP COLUMN.'); |
42 | 46 | ||
43 | $this->addSql('ALTER TABLE `'.$this->getTable('entry').'` DROP `uuid`'); | 47 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' DROP uuid'); |
44 | $this->addSql("DELETE FROM `".$this->getTable('craue_config_setting')."` WHERE `name` = 'share_public'"); | 48 | $this->addSql("DELETE FROM ".$this->getTable('craue_config_setting')." WHERE name = 'share_public'"); |
45 | } | 49 | } |
46 | } | 50 | } |
diff --git a/app/DoctrineMigrations/Version20160812120952.php b/app/DoctrineMigrations/Version20160812120952.php index a8d3bcf2..39423e2f 100644 --- a/app/DoctrineMigrations/Version20160812120952.php +++ b/app/DoctrineMigrations/Version20160812120952.php | |||
@@ -29,10 +29,17 @@ class Version20160812120952 extends AbstractMigration implements ContainerAwareI | |||
29 | */ | 29 | */ |
30 | public function up(Schema $schema) | 30 | public function up(Schema $schema) |
31 | { | 31 | { |
32 | if ($this->connection->getDatabasePlatform()->getName() == 'sqlite') { | 32 | switch ($this->connection->getDatabasePlatform()->getName()) { |
33 | $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext DEFAULT NULL'); | 33 | case 'sqlite': |
34 | } else { | 34 | $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext DEFAULT NULL'); |
35 | $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext COLLATE \'utf8_unicode_ci\' DEFAULT NULL'); | 35 | break; |
36 | |||
37 | case 'mysql': | ||
38 | $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext COLLATE \'utf8_unicode_ci\' DEFAULT NULL'); | ||
39 | break; | ||
40 | |||
41 | case 'postgresql': | ||
42 | $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name text DEFAULT NULL'); | ||
36 | } | 43 | } |
37 | } | 44 | } |
38 | 45 | ||
diff --git a/app/DoctrineMigrations/Version20160911214952.php b/app/DoctrineMigrations/Version20160911214952.php index 35809cec..3f988ccf 100644 --- a/app/DoctrineMigrations/Version20160911214952.php +++ b/app/DoctrineMigrations/Version20160911214952.php | |||
@@ -29,8 +29,8 @@ class Version20160911214952 extends AbstractMigration implements ContainerAwareI | |||
29 | */ | 29 | */ |
30 | public function up(Schema $schema) | 30 | public function up(Schema $schema) |
31 | { | 31 | { |
32 | $this->addSql('INSERT INTO `'.$this->getTable('craue_config_setting').'` (`name`, `value`, `section`) VALUES (\'import_with_redis\', \'0\', \'import\')'); | 32 | $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting').' (name, value, section) VALUES (\'import_with_redis\', \'0\', \'import\')'); |
33 | $this->addSql('INSERT INTO `'.$this->getTable('craue_config_setting').'` (`name`, `value`, `section`) VALUES (\'import_with_rabbitmq\', \'0\', \'import\')'); | 33 | $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting').' (name, value, section) VALUES (\'import_with_rabbitmq\', \'0\', \'import\')'); |
34 | } | 34 | } |
35 | 35 | ||
36 | /** | 36 | /** |
diff --git a/app/DoctrineMigrations/Version20160916201049.php b/app/DoctrineMigrations/Version20160916201049.php index 202901e6..fc4e700a 100644 --- a/app/DoctrineMigrations/Version20160916201049.php +++ b/app/DoctrineMigrations/Version20160916201049.php | |||
@@ -30,7 +30,7 @@ class Version20160916201049 extends AbstractMigration implements ContainerAwareI | |||
30 | public function up(Schema $schema) | 30 | public function up(Schema $schema) |
31 | { | 31 | { |
32 | $this->addSql('ALTER TABLE '.$this->getTable('config').' ADD pocket_consumer_key VARCHAR(255) DEFAULT NULL'); | 32 | $this->addSql('ALTER TABLE '.$this->getTable('config').' ADD pocket_consumer_key VARCHAR(255) DEFAULT NULL'); |
33 | $this->addSql("DELETE FROM `".$this->getTable('craue_config_setting')."` WHERE `name` = 'pocket_consumer_key';"); | 33 | $this->addSql("DELETE FROM ".$this->getTable('craue_config_setting')." WHERE name = 'pocket_consumer_key';"); |
34 | } | 34 | } |
35 | 35 | ||
36 | /** | 36 | /** |
@@ -40,7 +40,7 @@ class Version20160916201049 extends AbstractMigration implements ContainerAwareI | |||
40 | { | 40 | { |
41 | $this->abortIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); | 41 | $this->abortIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); |
42 | 42 | ||
43 | $this->addSql('ALTER TABLE `'.$this->getTable('config').'` DROP pocket_consumer_key'); | 43 | $this->addSql('ALTER TABLE '.$this->getTable('config').' DROP pocket_consumer_key'); |
44 | $this->addSql("INSERT INTO `".$this->getTable('craue_config_setting')."` (`name`, `value`, `section`) VALUES ('pocket_consumer_key', NULL, 'import')"); | 44 | $this->addSql("INSERT INTO ".$this->getTable('craue_config_setting')." (name, value, section) VALUES ('pocket_consumer_key', NULL, 'import')"); |
45 | } | 45 | } |
46 | } | 46 | } |
diff --git a/app/DoctrineMigrations/Version20161001072726.php b/app/DoctrineMigrations/Version20161001072726.php new file mode 100644 index 00000000..237db932 --- /dev/null +++ b/app/DoctrineMigrations/Version20161001072726.php | |||
@@ -0,0 +1,63 @@ | |||
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 | class Version20161001072726 extends AbstractMigration implements ContainerAwareInterface | ||
11 | { | ||
12 | /** | ||
13 | * @var ContainerInterface | ||
14 | */ | ||
15 | private $container; | ||
16 | |||
17 | public function setContainer(ContainerInterface $container = null) | ||
18 | { | ||
19 | $this->container = $container; | ||
20 | } | ||
21 | |||
22 | private function getTable($tableName) | ||
23 | { | ||
24 | return $this->container->getParameter('database_table_prefix') . $tableName; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * @param Schema $schema | ||
29 | */ | ||
30 | public function up(Schema $schema) | ||
31 | { | ||
32 | $this->skipIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); | ||
33 | |||
34 | // remove all FK from entry_tag | ||
35 | $query = $this->connection->query("SELECT CONSTRAINT_NAME FROM information_schema.key_column_usage WHERE TABLE_NAME = '".$this->getTable('entry_tag')."' AND CONSTRAINT_NAME LIKE 'FK_%' AND TABLE_SCHEMA = '".$this->connection->getDatabase()."'"); | ||
36 | $query->execute(); | ||
37 | |||
38 | foreach ($query->fetchAll() as $fk) { | ||
39 | $this->addSql('ALTER TABLE '.$this->getTable('entry_tag').' DROP FOREIGN KEY '.$fk['CONSTRAINT_NAME']); | ||
40 | } | ||
41 | |||
42 | $this->addSql('ALTER TABLE '.$this->getTable('entry_tag').' ADD CONSTRAINT FK_entry_tag_entry FOREIGN KEY (entry_id) REFERENCES '.$this->getTable('entry').' (id) ON DELETE CASCADE'); | ||
43 | $this->addSql('ALTER TABLE '.$this->getTable('entry_tag').' ADD CONSTRAINT FK_entry_tag_tag FOREIGN KEY (tag_id) REFERENCES '.$this->getTable('tag').' (id) ON DELETE CASCADE'); | ||
44 | |||
45 | // remove entry FK from annotation | ||
46 | $query = $this->connection->query("SELECT CONSTRAINT_NAME FROM information_schema.key_column_usage WHERE TABLE_NAME = '".$this->getTable('annotation')."' AND CONSTRAINT_NAME LIKE 'FK_%' and COLUMN_NAME = 'entry_id' AND TABLE_SCHEMA = '".$this->connection->getDatabase()."'"); | ||
47 | $query->execute(); | ||
48 | |||
49 | foreach ($query->fetchAll() as $fk) { | ||
50 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' DROP FOREIGN KEY '.$fk['CONSTRAINT_NAME']); | ||
51 | } | ||
52 | |||
53 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' ADD CONSTRAINT FK_annotation_entry FOREIGN KEY (entry_id) REFERENCES '.$this->getTable('entry').' (id) ON DELETE CASCADE'); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * @param Schema $schema | ||
58 | */ | ||
59 | public function down(Schema $schema) | ||
60 | { | ||
61 | throw new SkipMigrationException('Too complex ...'); | ||
62 | } | ||
63 | } | ||
diff --git a/app/DoctrineMigrations/Version20161022134138.php b/app/DoctrineMigrations/Version20161022134138.php new file mode 100644 index 00000000..5cce55a5 --- /dev/null +++ b/app/DoctrineMigrations/Version20161022134138.php | |||
@@ -0,0 +1,77 @@ | |||
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 | class Version20161022134138 extends AbstractMigration implements ContainerAwareInterface | ||
11 | { | ||
12 | /** | ||
13 | * @var ContainerInterface | ||
14 | */ | ||
15 | private $container; | ||
16 | |||
17 | public function setContainer(ContainerInterface $container = null) | ||
18 | { | ||
19 | $this->container = $container; | ||
20 | } | ||
21 | |||
22 | private function getTable($tableName) | ||
23 | { | ||
24 | return $this->container->getParameter('database_table_prefix') . $tableName; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * @param Schema $schema | ||
29 | */ | ||
30 | public function up(Schema $schema) | ||
31 | { | ||
32 | $this->skipIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'This migration only apply to MySQL'); | ||
33 | |||
34 | $this->addSql('ALTER DATABASE '.$this->container->getParameter('database_name').' CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;'); | ||
35 | |||
36 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
37 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
38 | $this->addSql('ALTER TABLE '.$this->getTable('tag').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
39 | $this->addSql('ALTER TABLE '.$this->getTable('user').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
40 | |||
41 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `text` `text` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
42 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `quote` `quote` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
43 | |||
44 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `title` `title` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
45 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `content` `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
46 | |||
47 | $this->addSql('ALTER TABLE '.$this->getTable('tag').' CHANGE `label` `label` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
48 | |||
49 | $this->addSql('ALTER TABLE '.$this->getTable('user').' CHANGE `name` `name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * @param Schema $schema | ||
54 | */ | ||
55 | public function down(Schema $schema) | ||
56 | { | ||
57 | $this->skipIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'This migration only apply to MySQL'); | ||
58 | |||
59 | $this->addSql('ALTER DATABASE '.$this->container->getParameter('database_name').' CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;'); | ||
60 | |||
61 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
62 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
63 | $this->addSql('ALTER TABLE '.$this->getTable('tag').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
64 | $this->addSql('ALTER TABLE '.$this->getTable('user').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
65 | |||
66 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `text` `text` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
67 | $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `quote` `quote` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
68 | |||
69 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `title` `title` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
70 | $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `content` `content` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
71 | |||
72 | $this->addSql('ALTER TABLE '.$this->getTable('tag').' CHANGE `label` `label` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
73 | |||
74 | $this->addSql('ALTER TABLE '.$this->getTable('user').' CHANGE `name` `name` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); | ||
75 | |||
76 | } | ||
77 | } | ||
diff --git a/app/config/config.yml b/app/config/config.yml index b4760073..9dbc9d7c 100644 --- a/app/config/config.yml +++ b/app/config/config.yml | |||
@@ -75,7 +75,7 @@ doctrine: | |||
75 | dbname: "%database_name%" | 75 | dbname: "%database_name%" |
76 | user: "%database_user%" | 76 | user: "%database_user%" |
77 | password: "%database_password%" | 77 | password: "%database_password%" |
78 | charset: UTF8 | 78 | charset: "%database_charset%" |
79 | path: "%database_path%" | 79 | path: "%database_path%" |
80 | unix_socket: "%database_socket%" | 80 | unix_socket: "%database_socket%" |
81 | server_version: 5.6 | 81 | server_version: 5.6 |
diff --git a/app/config/config_test.yml b/app/config/config_test.yml index 3eab6fb2..f5e2c25e 100644 --- a/app/config/config_test.yml +++ b/app/config/config_test.yml | |||
@@ -28,7 +28,7 @@ doctrine: | |||
28 | dbname: "%test_database_name%" | 28 | dbname: "%test_database_name%" |
29 | user: "%test_database_user%" | 29 | user: "%test_database_user%" |
30 | password: "%test_database_password%" | 30 | password: "%test_database_password%" |
31 | charset: UTF8 | 31 | charset: "%test_database_charset%" |
32 | path: "%test_database_path%" | 32 | path: "%test_database_path%" |
33 | orm: | 33 | orm: |
34 | metadata_cache_driver: | 34 | metadata_cache_driver: |
diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index ece4903a..7a22cb98 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist | |||
@@ -19,16 +19,18 @@ parameters: | |||
19 | database_path: "%kernel.root_dir%/../data/db/wallabag.sqlite" | 19 | database_path: "%kernel.root_dir%/../data/db/wallabag.sqlite" |
20 | database_table_prefix: wallabag_ | 20 | database_table_prefix: wallabag_ |
21 | database_socket: null | 21 | database_socket: null |
22 | # with MySQL, use "utf8mb4" if you got problem with content with emojis | ||
23 | database_charset: utf8 | ||
22 | 24 | ||
23 | mailer_transport: smtp | 25 | mailer_transport: smtp |
24 | mailer_host: 127.0.0.1 | 26 | mailer_host: 127.0.0.1 |
25 | mailer_user: ~ | 27 | mailer_user: ~ |
26 | mailer_password: ~ | 28 | mailer_password: ~ |
27 | 29 | ||
28 | locale: en | 30 | locale: en |
29 | 31 | ||
30 | # A secret key that's used to generate certain security-related tokens | 32 | # A secret key that's used to generate certain security-related tokens |
31 | secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv | 33 | secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv |
32 | 34 | ||
33 | # two factor stuff | 35 | # two factor stuff |
34 | twofactor_auth: true | 36 | twofactor_auth: true |
diff --git a/app/config/parameters_test.yml b/app/config/parameters_test.yml index 2943b27a..5f2e25bb 100644 --- a/app/config/parameters_test.yml +++ b/app/config/parameters_test.yml | |||
@@ -6,3 +6,4 @@ parameters: | |||
6 | test_database_user: null | 6 | test_database_user: null |
7 | test_database_password: null | 7 | test_database_password: null |
8 | test_database_path: '%kernel.root_dir%/../data/db/wallabag_test.sqlite' | 8 | test_database_path: '%kernel.root_dir%/../data/db/wallabag_test.sqlite' |
9 | test_database_charset: utf8 | ||
diff --git a/app/config/tests/parameters_test.mysql.yml b/app/config/tests/parameters_test.mysql.yml index d8512845..bca2d466 100644 --- a/app/config/tests/parameters_test.mysql.yml +++ b/app/config/tests/parameters_test.mysql.yml | |||
@@ -6,3 +6,4 @@ parameters: | |||
6 | test_database_user: root | 6 | test_database_user: root |
7 | test_database_password: ~ | 7 | test_database_password: ~ |
8 | test_database_path: ~ | 8 | test_database_path: ~ |
9 | test_database_charset: utf8mb4 | ||
diff --git a/app/config/tests/parameters_test.pgsql.yml b/app/config/tests/parameters_test.pgsql.yml index 41383868..3e18d4a0 100644 --- a/app/config/tests/parameters_test.pgsql.yml +++ b/app/config/tests/parameters_test.pgsql.yml | |||
@@ -6,3 +6,4 @@ parameters: | |||
6 | test_database_user: travis | 6 | test_database_user: travis |
7 | test_database_password: ~ | 7 | test_database_password: ~ |
8 | test_database_path: ~ | 8 | test_database_path: ~ |
9 | test_database_charset: utf8 | ||
diff --git a/app/config/tests/parameters_test.sqlite.yml b/app/config/tests/parameters_test.sqlite.yml index 1952e3a6..b8a5f41a 100644 --- a/app/config/tests/parameters_test.sqlite.yml +++ b/app/config/tests/parameters_test.sqlite.yml | |||
@@ -6,3 +6,4 @@ parameters: | |||
6 | test_database_user: ~ | 6 | test_database_user: ~ |
7 | test_database_password: ~ | 7 | test_database_password: ~ |
8 | test_database_path: "%kernel.root_dir%/../data/db/wallabag_test.sqlite" | 8 | test_database_path: "%kernel.root_dir%/../data/db/wallabag_test.sqlite" |
9 | test_database_charset: utf8 | ||
diff --git a/docs/en/user/parameters.rst b/docs/en/user/parameters.rst index 79c50871..2fca020e 100644 --- a/docs/en/user/parameters.rst +++ b/docs/en/user/parameters.rst | |||
@@ -11,7 +11,8 @@ What is the meaning of the parameters? | |||
11 | "database_password", "~", "password of that user" | 11 | "database_password", "~", "password of that user" |
12 | "database_path", "``""%kernel.root_dir%/../data/db/wallabag.sqlite""``", "only for SQLite, define where to put the database file. Leave it for other database" | 12 | "database_path", "``""%kernel.root_dir%/../data/db/wallabag.sqlite""``", "only for SQLite, define where to put the database file. Leave it for other database" |
13 | "database_table_prefix", "wallabag_", "all wallabag's tables will be prefixed with that string. You can include a ``_`` for clarity" | 13 | "database_table_prefix", "wallabag_", "all wallabag's tables will be prefixed with that string. You can include a ``_`` for clarity" |
14 | "database_socket", "null", "If your database is using a socket instead of tcp, put the path of the socket (other connection parameters will then be ignored" | 14 | "database_socket", "null", "If your database is using a socket instead of tcp, put the path of the socket (other connection parameters will then be ignored)" |
15 | "database_charset", "utf8mb4", "For PostgreSQL & SQLite you should use utf8, for MySQL use utf8mb4 which handle emoji" | ||
15 | 16 | ||
16 | .. csv-table:: Configuration to send emails from wallabag | 17 | .. csv-table:: Configuration to send emails from wallabag |
17 | :header: "name", "default", "description" | 18 | :header: "name", "default", "description" |
diff --git a/src/Wallabag/AnnotationBundle/Entity/Annotation.php b/src/Wallabag/AnnotationBundle/Entity/Annotation.php index c48d8731..0838f5aa 100644 --- a/src/Wallabag/AnnotationBundle/Entity/Annotation.php +++ b/src/Wallabag/AnnotationBundle/Entity/Annotation.php | |||
@@ -82,7 +82,7 @@ class Annotation | |||
82 | * @Exclude | 82 | * @Exclude |
83 | * | 83 | * |
84 | * @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Entry", inversedBy="annotations") | 84 | * @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Entry", inversedBy="annotations") |
85 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id") | 85 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="cascade") |
86 | */ | 86 | */ |
87 | private $entry; | 87 | private $entry; |
88 | 88 | ||
diff --git a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php index 8cccffba..8d3f07ee 100644 --- a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php +++ b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php | |||
@@ -108,4 +108,18 @@ class AnnotationRepository extends EntityRepository | |||
108 | ->getQuery() | 108 | ->getQuery() |
109 | ->getSingleResult(); | 109 | ->getSingleResult(); |
110 | } | 110 | } |
111 | |||
112 | /** | ||
113 | * Remove all annotations for a user id. | ||
114 | * Used when a user want to reset all informations. | ||
115 | * | ||
116 | * @param int $userId | ||
117 | */ | ||
118 | public function removeAllByUserId($userId) | ||
119 | { | ||
120 | $this->getEntityManager() | ||
121 | ->createQuery('DELETE FROM Wallabag\AnnotationBundle\Entity\Annotation a WHERE a.user = :userId') | ||
122 | ->setParameter('userId', $userId) | ||
123 | ->execute(); | ||
124 | } | ||
111 | } | 125 | } |
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index 59110782..82cd9daf 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php | |||
@@ -40,7 +40,7 @@ class InstallCommand extends ContainerAwareCommand | |||
40 | { | 40 | { |
41 | $this | 41 | $this |
42 | ->setName('wallabag:install') | 42 | ->setName('wallabag:install') |
43 | ->setDescription('Wallabag installer.') | 43 | ->setDescription('wallabag installer.') |
44 | ->addOption( | 44 | ->addOption( |
45 | 'reset', | 45 | 'reset', |
46 | null, | 46 | null, |
@@ -55,7 +55,7 @@ class InstallCommand extends ContainerAwareCommand | |||
55 | $this->defaultInput = $input; | 55 | $this->defaultInput = $input; |
56 | $this->defaultOutput = $output; | 56 | $this->defaultOutput = $output; |
57 | 57 | ||
58 | $output->writeln('<info>Installing Wallabag...</info>'); | 58 | $output->writeln('<info>Installing wallabag...</info>'); |
59 | $output->writeln(''); | 59 | $output->writeln(''); |
60 | 60 | ||
61 | $this | 61 | $this |
@@ -65,7 +65,7 @@ class InstallCommand extends ContainerAwareCommand | |||
65 | ->setupConfig() | 65 | ->setupConfig() |
66 | ; | 66 | ; |
67 | 67 | ||
68 | $output->writeln('<info>Wallabag has been successfully installed.</info>'); | 68 | $output->writeln('<info>wallabag has been successfully installed.</info>'); |
69 | $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>'); | 69 | $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>'); |
70 | } | 70 | } |
71 | 71 | ||
@@ -95,7 +95,8 @@ class InstallCommand extends ContainerAwareCommand | |||
95 | $help = ''; | 95 | $help = ''; |
96 | 96 | ||
97 | try { | 97 | try { |
98 | $this->getContainer()->get('doctrine')->getManager()->getConnection()->connect(); | 98 | $conn = $this->getContainer()->get('doctrine')->getManager()->getConnection(); |
99 | $conn->connect(); | ||
99 | } catch (\Exception $e) { | 100 | } catch (\Exception $e) { |
100 | if (false === strpos($e->getMessage(), 'Unknown database') | 101 | if (false === strpos($e->getMessage(), 'Unknown database') |
101 | && false === strpos($e->getMessage(), 'database "'.$this->getContainer()->getParameter('database_name').'" does not exist')) { | 102 | && false === strpos($e->getMessage(), 'database "'.$this->getContainer()->getParameter('database_name').'" does not exist')) { |
@@ -107,6 +108,21 @@ class InstallCommand extends ContainerAwareCommand | |||
107 | 108 | ||
108 | $rows[] = [$label, $status, $help]; | 109 | $rows[] = [$label, $status, $help]; |
109 | 110 | ||
111 | // now check if MySQL isn't too old to handle utf8mb4 | ||
112 | if ($conn->isConnected() && $conn->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform) { | ||
113 | $version = $conn->query('select version()')->fetchColumn(); | ||
114 | $minimalVersion = '5.5.4'; | ||
115 | |||
116 | if (false === version_compare($version, $minimalVersion, '>')) { | ||
117 | $fulfilled = false; | ||
118 | $rows[] = [ | ||
119 | '<comment>Database version</comment>', | ||
120 | '<error>ERROR!</error>', | ||
121 | 'Your MySQL version ('.$version.') is too old, consider upgrading ('.$minimalVersion.'+).', | ||
122 | ]; | ||
123 | } | ||
124 | } | ||
125 | |||
110 | foreach ($this->functionExists as $functionRequired) { | 126 | foreach ($this->functionExists as $functionRequired) { |
111 | $label = '<comment>'.$functionRequired.'</comment>'; | 127 | $label = '<comment>'.$functionRequired.'</comment>'; |
112 | $status = '<info>OK!</info>'; | 128 | $status = '<info>OK!</info>'; |
@@ -131,7 +147,7 @@ class InstallCommand extends ContainerAwareCommand | |||
131 | throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); | 147 | throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); |
132 | } | 148 | } |
133 | 149 | ||
134 | $this->defaultOutput->writeln('<info>Success! Your system can run Wallabag properly.</info>'); | 150 | $this->defaultOutput->writeln('<info>Success! Your system can run wallabag properly.</info>'); |
135 | 151 | ||
136 | $this->defaultOutput->writeln(''); | 152 | $this->defaultOutput->writeln(''); |
137 | 153 | ||
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index abd35c02..8d391917 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php | |||
@@ -225,6 +225,80 @@ class ConfigController extends Controller | |||
225 | } | 225 | } |
226 | 226 | ||
227 | /** | 227 | /** |
228 | * Remove all annotations OR tags OR entries for the current user. | ||
229 | * | ||
230 | * @Route("/reset/{type}", requirements={"id" = "annotations|tags|entries"}, name="config_reset") | ||
231 | * | ||
232 | * @return RedirectResponse | ||
233 | */ | ||
234 | public function resetAction($type) | ||
235 | { | ||
236 | $em = $this->getDoctrine()->getManager(); | ||
237 | |||
238 | switch ($type) { | ||
239 | case 'annotations': | ||
240 | $this->getDoctrine() | ||
241 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
242 | ->removeAllByUserId($this->getUser()->getId()); | ||
243 | break; | ||
244 | |||
245 | case 'tags': | ||
246 | $this->removeAllTagsByUserId($this->getUser()->getId()); | ||
247 | break; | ||
248 | |||
249 | case 'entries': | ||
250 | // SQLite doesn't care about cascading remove, so we need to manually remove associated stuf | ||
251 | // otherwise they won't be removed ... | ||
252 | if ($this->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) { | ||
253 | $this->getDoctrine()->getRepository('WallabagAnnotationBundle:Annotation')->removeAllByUserId($this->getUser()->getId()); | ||
254 | } | ||
255 | |||
256 | // manually remove tags to avoid orphan tag | ||
257 | $this->removeAllTagsByUserId($this->getUser()->getId()); | ||
258 | |||
259 | $this->getDoctrine() | ||
260 | ->getRepository('WallabagCoreBundle:Entry') | ||
261 | ->removeAllByUserId($this->getUser()->getId()); | ||
262 | } | ||
263 | |||
264 | $this->get('session')->getFlashBag()->add( | ||
265 | 'notice', | ||
266 | 'flashes.config.notice.'.$type.'_reset' | ||
267 | ); | ||
268 | |||
269 | return $this->redirect($this->generateUrl('config').'#set3'); | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Remove all tags for a given user and cleanup orphan tags. | ||
274 | * | ||
275 | * @param int $userId | ||
276 | */ | ||
277 | private function removeAllTagsByUserId($userId) | ||
278 | { | ||
279 | $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId); | ||
280 | |||
281 | if (empty($tags)) { | ||
282 | return; | ||
283 | } | ||
284 | |||
285 | $this->getDoctrine() | ||
286 | ->getRepository('WallabagCoreBundle:Entry') | ||
287 | ->removeTags($userId, $tags); | ||
288 | |||
289 | // cleanup orphan tags | ||
290 | $em = $this->getDoctrine()->getManager(); | ||
291 | |||
292 | foreach ($tags as $tag) { | ||
293 | if (count($tag->getEntries()) === 0) { | ||
294 | $em->remove($tag); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | $em->flush(); | ||
299 | } | ||
300 | |||
301 | /** | ||
228 | * Validate that a rule can be edited/deleted by the current user. | 302 | * Validate that a rule can be edited/deleted by the current user. |
229 | * | 303 | * |
230 | * @param TaggingRule $rule | 304 | * @param TaggingRule $rule |
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php index 5acc6852..4542d484 100644 --- a/src/Wallabag/CoreBundle/Controller/TagController.php +++ b/src/Wallabag/CoreBundle/Controller/TagController.php | |||
@@ -90,15 +90,15 @@ class TagController extends Controller | |||
90 | 90 | ||
91 | $flatTags = []; | 91 | $flatTags = []; |
92 | 92 | ||
93 | foreach ($tags as $key => $tag) { | 93 | foreach ($tags as $tag) { |
94 | $nbEntries = $this->getDoctrine() | 94 | $nbEntries = $this->getDoctrine() |
95 | ->getRepository('WallabagCoreBundle:Entry') | 95 | ->getRepository('WallabagCoreBundle:Entry') |
96 | ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag['id']); | 96 | ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag->getId()); |
97 | 97 | ||
98 | $flatTags[] = [ | 98 | $flatTags[] = [ |
99 | 'id' => $tag['id'], | 99 | 'id' => $tag->getId(), |
100 | 'label' => $tag['label'], | 100 | 'label' => $tag->getLabel(), |
101 | 'slug' => $tag['slug'], | 101 | 'slug' => $tag->getSlug(), |
102 | 'nbEntries' => $nbEntries, | 102 | 'nbEntries' => $nbEntries, |
103 | ]; | 103 | ]; |
104 | } | 104 | } |
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index f2da3f4d..dd0f7e67 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php | |||
@@ -19,7 +19,7 @@ use Wallabag\AnnotationBundle\Entity\Annotation; | |||
19 | * | 19 | * |
20 | * @XmlRoot("entry") | 20 | * @XmlRoot("entry") |
21 | * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository") | 21 | * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository") |
22 | * @ORM\Table(name="`entry`") | 22 | * @ORM\Table(name="`entry`", options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"}) |
23 | * @ORM\HasLifecycleCallbacks() | 23 | * @ORM\HasLifecycleCallbacks() |
24 | * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())") | 24 | * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())") |
25 | */ | 25 | */ |
@@ -190,10 +190,10 @@ class Entry | |||
190 | * @ORM\JoinTable( | 190 | * @ORM\JoinTable( |
191 | * name="entry_tag", | 191 | * name="entry_tag", |
192 | * joinColumns={ | 192 | * joinColumns={ |
193 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id") | 193 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="cascade") |
194 | * }, | 194 | * }, |
195 | * inverseJoinColumns={ | 195 | * inverseJoinColumns={ |
196 | * @ORM\JoinColumn(name="tag_id", referencedColumnName="id") | 196 | * @ORM\JoinColumn(name="tag_id", referencedColumnName="id", onDelete="cascade") |
197 | * } | 197 | * } |
198 | * ) | 198 | * ) |
199 | */ | 199 | */ |
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index cd2b47b9..14616d88 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -329,4 +329,18 @@ class EntryRepository extends EntityRepository | |||
329 | 329 | ||
330 | return $qb->getQuery()->getSingleScalarResult(); | 330 | return $qb->getQuery()->getSingleScalarResult(); |
331 | } | 331 | } |
332 | |||
333 | /** | ||
334 | * Remove all entries for a user id. | ||
335 | * Used when a user want to reset all informations. | ||
336 | * | ||
337 | * @param int $userId | ||
338 | */ | ||
339 | public function removeAllByUserId($userId) | ||
340 | { | ||
341 | $this->getEntityManager() | ||
342 | ->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = :userId') | ||
343 | ->setParameter('userId', $userId) | ||
344 | ->execute(); | ||
345 | } | ||
332 | } | 346 | } |
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php index e76878d4..81445989 100644 --- a/src/Wallabag/CoreBundle/Repository/TagRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php | |||
@@ -34,6 +34,9 @@ class TagRepository extends EntityRepository | |||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Find all tags per user. | 36 | * Find all tags per user. |
37 | * Instead of just left joined on the Entry table, we select only id and group by id to avoid tag multiplication in results. | ||
38 | * Once we have all tags id, we can safely request them one by one. | ||
39 | * This'll still be fastest than the previous query. | ||
37 | * | 40 | * |
38 | * @param int $userId | 41 | * @param int $userId |
39 | * | 42 | * |
@@ -41,15 +44,20 @@ class TagRepository extends EntityRepository | |||
41 | */ | 44 | */ |
42 | public function findAllTags($userId) | 45 | public function findAllTags($userId) |
43 | { | 46 | { |
44 | return $this->createQueryBuilder('t') | 47 | $ids = $this->createQueryBuilder('t') |
45 | ->select('t.slug', 't.label', 't.id') | 48 | ->select('t.id') |
46 | ->leftJoin('t.entries', 'e') | 49 | ->leftJoin('t.entries', 'e') |
47 | ->where('e.user = :userId')->setParameter('userId', $userId) | 50 | ->where('e.user = :userId')->setParameter('userId', $userId) |
48 | ->groupBy('t.slug') | 51 | ->groupBy('t.id') |
49 | ->addGroupBy('t.label') | ||
50 | ->addGroupBy('t.id') | ||
51 | ->getQuery() | 52 | ->getQuery() |
52 | ->getArrayResult(); | 53 | ->getArrayResult(); |
54 | |||
55 | $tags = []; | ||
56 | foreach ($ids as $id) { | ||
57 | $tags[] = $this->find($id); | ||
58 | } | ||
59 | |||
60 | return $tags; | ||
53 | } | 61 | } |
54 | 62 | ||
55 | /** | 63 | /** |
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml index a4b727f4..048a72fc 100644 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ b/src/Wallabag/CoreBundle/Resources/config/services.yml | |||
@@ -129,3 +129,10 @@ services: | |||
129 | arguments: | 129 | arguments: |
130 | - '@twig' | 130 | - '@twig' |
131 | - '%kernel.debug%' | 131 | - '%kernel.debug%' |
132 | |||
133 | wallabag_core.subscriber.sqlite_cascade_delete: | ||
134 | class: Wallabag\CoreBundle\Subscriber\SQLiteCascadeDeleteSubscriber | ||
135 | arguments: | ||
136 | - "@doctrine" | ||
137 | tags: | ||
138 | - { name: doctrine.event_subscriber } | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml index f5548a21..7c8ae66e 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'Emailadresse' | 89 | email_label: 'Emailadresse' |
90 | # twoFactorAuthentication_label: 'Two factor authentication' | 90 | # twoFactorAuthentication_label: 'Two factor authentication' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Gammel adgangskode' | 104 | old_password_label: 'Gammel adgangskode' |
98 | new_password_label: 'Ny adgangskode' | 105 | new_password_label: 'Ny adgangskode' |
@@ -462,6 +469,9 @@ flashes: | |||
462 | # tagging_rules_deleted: 'Tagging rule deleted' | 469 | # tagging_rules_deleted: 'Tagging rule deleted' |
463 | # user_added: 'User "%username%" added' | 470 | # user_added: 'User "%username%" added' |
464 | # rss_token_updated: 'RSS token updated' | 471 | # rss_token_updated: 'RSS token updated' |
472 | # annotations_reset: Annotations reset | ||
473 | # tags_reset: Tags reset | ||
474 | # entries_reset: Entries reset | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | # entry_already_saved: 'Entry already saved on %date%' | 477 | # entry_already_saved: 'Entry already saved on %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml index 9edd7fb7..20f9753b 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'E-Mail-Adresse' | 89 | email_label: 'E-Mail-Adresse' |
90 | twoFactorAuthentication_label: 'Zwei-Faktor-Authentifizierung' | 90 | twoFactorAuthentication_label: 'Zwei-Faktor-Authentifizierung' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Altes Kennwort' | 104 | old_password_label: 'Altes Kennwort' |
98 | new_password_label: 'Neues Kennwort' | 105 | new_password_label: 'Neues Kennwort' |
@@ -462,6 +469,9 @@ flashes: | |||
462 | tagging_rules_deleted: 'Tagging-Regel gelöscht' | 469 | tagging_rules_deleted: 'Tagging-Regel gelöscht' |
463 | user_added: 'Benutzer "%username%" erstellt' | 470 | user_added: 'Benutzer "%username%" erstellt' |
464 | rss_token_updated: 'RSS-Token aktualisiert' | 471 | rss_token_updated: 'RSS-Token aktualisiert' |
472 | # annotations_reset: Annotations reset | ||
473 | # tags_reset: Tags reset | ||
474 | # entries_reset: Entries reset | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | entry_already_saved: 'Eintrag bereits am %date% gespeichert' | 477 | entry_already_saved: 'Eintrag bereits am %date% gespeichert' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml index b86145a0..35dde535 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'Email' | 89 | email_label: 'Email' |
90 | twoFactorAuthentication_label: 'Two factor authentication' | 90 | twoFactorAuthentication_label: 'Two factor authentication' |
91 | delete: | 91 | delete: |
92 | title: Delete my account (danger zone !) | 92 | title: Delete my account (a.k.a danger zone) |
93 | description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | confirm: Are you really sure? (it can't be UNDONE) | 94 | confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | button: Delete my account | 95 | button: Delete my account |
96 | reset: | ||
97 | title: Reset area (a.k.a danger zone) | ||
98 | description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | annotations: Remove ALL annotations | ||
100 | tags: Remove ALL tags | ||
101 | entries: Remove ALL entries | ||
102 | confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Current password' | 104 | old_password_label: 'Current password' |
98 | new_password_label: 'New password' | 105 | new_password_label: 'New password' |
@@ -461,6 +468,9 @@ flashes: | |||
461 | tagging_rules_updated: 'Tagging rules updated' | 468 | tagging_rules_updated: 'Tagging rules updated' |
462 | tagging_rules_deleted: 'Tagging rule deleted' | 469 | tagging_rules_deleted: 'Tagging rule deleted' |
463 | rss_token_updated: 'RSS token updated' | 470 | rss_token_updated: 'RSS token updated' |
471 | annotations_reset: Annotations reset | ||
472 | tags_reset: Tags reset | ||
473 | entries_reset: Entries reset | ||
464 | entry: | 474 | entry: |
465 | notice: | 475 | notice: |
466 | entry_already_saved: 'Entry already saved on %date%' | 476 | entry_already_saved: 'Entry already saved on %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml index b7187f50..13f2e977 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'Direccion e-mail' | 89 | email_label: 'Direccion e-mail' |
90 | twoFactorAuthentication_label: 'Autentificación de dos factores' | 90 | twoFactorAuthentication_label: 'Autentificación de dos factores' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Contraseña actual' | 104 | old_password_label: 'Contraseña actual' |
98 | new_password_label: 'Nueva contraseña' | 105 | new_password_label: 'Nueva contraseña' |
@@ -462,6 +469,9 @@ flashes: | |||
462 | tagging_rules_deleted: 'Regla de etiquetado actualizada' | 469 | tagging_rules_deleted: 'Regla de etiquetado actualizada' |
463 | user_added: 'Usuario "%username%" añadido' | 470 | user_added: 'Usuario "%username%" añadido' |
464 | rss_token_updated: 'RSS token actualizado' | 471 | rss_token_updated: 'RSS token actualizado' |
472 | # annotations_reset: Annotations reset | ||
473 | # tags_reset: Tags reset | ||
474 | # entries_reset: Entries reset | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | entry_already_saved: 'Entrada ya guardada por %fecha%' | 477 | entry_already_saved: 'Entrada ya guardada por %fecha%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml index 0751752b..5ee1f62d 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'نشانی ایمیل' | 89 | email_label: 'نشانی ایمیل' |
90 | twoFactorAuthentication_label: 'تأیید ۲مرحلهای' | 90 | twoFactorAuthentication_label: 'تأیید ۲مرحلهای' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'رمز قدیمی' | 104 | old_password_label: 'رمز قدیمی' |
98 | new_password_label: 'رمز تازه' | 105 | new_password_label: 'رمز تازه' |
@@ -461,6 +468,9 @@ flashes: | |||
461 | tagging_rules_deleted: 'قانون برچسبگذاری پاک شد' | 468 | tagging_rules_deleted: 'قانون برچسبگذاری پاک شد' |
462 | user_added: 'کابر "%username%" افزوده شد' | 469 | user_added: 'کابر "%username%" افزوده شد' |
463 | rss_token_updated: 'کد آر-اس-اس بهروز شد' | 470 | rss_token_updated: 'کد آر-اس-اس بهروز شد' |
471 | # annotations_reset: Annotations reset | ||
472 | # tags_reset: Tags reset | ||
473 | # entries_reset: Entries reset | ||
464 | entry: | 474 | entry: |
465 | notice: | 475 | notice: |
466 | entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود' | 476 | entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index 8d19ccb1..14bdbbc7 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml | |||
@@ -91,8 +91,15 @@ config: | |||
91 | delete: | 91 | delete: |
92 | title: Supprimer mon compte (attention danger !) | 92 | title: Supprimer mon compte (attention danger !) |
93 | description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté. | 93 | description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté. |
94 | confirm: Vous êtes vraiment sûr ? (c'est IRRÉVERSIBLE !) | 94 | confirm: Vous êtes vraiment sûr ? (C'EST IRRÉVERSIBLE) |
95 | button: 'Supprimer mon compte' | 95 | button: 'Supprimer mon compte' |
96 | reset: | ||
97 | title: Réinitialisation (attention danger !) | ||
98 | description: En cliquant sur les boutons ci-dessous vous avez la possibilité de supprimer certaines informations de votre compte. Attention, ces actions sont IRRÉVERSIBLES ! | ||
99 | annotations: Supprimer TOUTES les annotations | ||
100 | tags: Supprimer TOUS les tags | ||
101 | entries: Supprimer TOUS les articles | ||
102 | confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Mot de passe actuel' | 104 | old_password_label: 'Mot de passe actuel' |
98 | new_password_label: 'Nouveau mot de passe' | 105 | new_password_label: 'Nouveau mot de passe' |
@@ -391,7 +398,7 @@ developer: | |||
391 | field_grant_types: 'Type de privilège accordé' | 398 | field_grant_types: 'Type de privilège accordé' |
392 | no_client: 'Aucun client pour le moment' | 399 | no_client: 'Aucun client pour le moment' |
393 | remove: | 400 | remove: |
394 | warn_message_1: 'Vous avez la possibilité de supprimer le client %name%. Cette action est IRREVERSIBLE !' | 401 | warn_message_1: 'Vous avez la possibilité de supprimer le client %name%. Cette action est IRRÉVERSIBLE !' |
395 | warn_message_2: "Si vous supprimez le client %name%, toutes les applications qui l'utilisaient ne fonctionneront plus avec votre compte wallabag." | 402 | warn_message_2: "Si vous supprimez le client %name%, toutes les applications qui l'utilisaient ne fonctionneront plus avec votre compte wallabag." |
396 | action: 'Supprimer le client %name%' | 403 | action: 'Supprimer le client %name%' |
397 | client: | 404 | client: |
@@ -462,9 +469,12 @@ flashes: | |||
462 | tagging_rules_deleted: 'Règle supprimée' | 469 | tagging_rules_deleted: 'Règle supprimée' |
463 | user_added: 'Utilisateur "%username%" ajouté' | 470 | user_added: 'Utilisateur "%username%" ajouté' |
464 | rss_token_updated: 'Jeton RSS mis à jour' | 471 | rss_token_updated: 'Jeton RSS mis à jour' |
472 | annotations_reset: Annotations supprimées | ||
473 | tags_reset: Tags supprimés | ||
474 | entries_reset: Articles supprimés | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | entry_already_saved: 'Article déjà sauvergardé le %date%' | 477 | entry_already_saved: 'Article déjà sauvegardé le %date%' |
468 | entry_saved: 'Article enregistré' | 478 | entry_saved: 'Article enregistré' |
469 | entry_saved_failed: 'Article enregistré mais impossible de récupérer le contenu' | 479 | entry_saved_failed: 'Article enregistré mais impossible de récupérer le contenu' |
470 | entry_updated: 'Article mis à jour' | 480 | entry_updated: 'Article mis à jour' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml index 4d3452ea..bc4448bd 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'E-mail' | 89 | email_label: 'E-mail' |
90 | twoFactorAuthentication_label: 'Two factor authentication' | 90 | twoFactorAuthentication_label: 'Two factor authentication' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Password corrente' | 104 | old_password_label: 'Password corrente' |
98 | new_password_label: 'Nuova password' | 105 | new_password_label: 'Nuova password' |
@@ -462,6 +469,9 @@ flashes: | |||
462 | tagging_rules_deleted: 'Regola di tagging aggiornate' | 469 | tagging_rules_deleted: 'Regola di tagging aggiornate' |
463 | user_added: 'Utente "%username%" aggiunto' | 470 | user_added: 'Utente "%username%" aggiunto' |
464 | rss_token_updated: 'RSS token aggiornato' | 471 | rss_token_updated: 'RSS token aggiornato' |
472 | # annotations_reset: Annotations reset | ||
473 | # tags_reset: Tags reset | ||
474 | # entries_reset: Entries reset | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | entry_already_saved: 'Contenuto già salvato in data %date%' | 477 | entry_already_saved: 'Contenuto già salvato in data %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml index f14213c6..7d1a801a 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'Adreça de corrièl' | 89 | email_label: 'Adreça de corrièl' |
90 | twoFactorAuthentication_label: 'Dobla autentificacion' | 90 | twoFactorAuthentication_label: 'Dobla autentificacion' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Senhal actual' | 104 | old_password_label: 'Senhal actual' |
98 | new_password_label: 'Senhal novèl' | 105 | new_password_label: 'Senhal novèl' |
@@ -462,6 +469,9 @@ flashes: | |||
462 | tagging_rules_deleted: 'Règla suprimida' | 469 | tagging_rules_deleted: 'Règla suprimida' |
463 | user_added: 'Utilizaire "%username%" ajustat' | 470 | user_added: 'Utilizaire "%username%" ajustat' |
464 | rss_token_updated: 'Geton RSS mes a jorn' | 471 | rss_token_updated: 'Geton RSS mes a jorn' |
472 | # annotations_reset: Annotations reset | ||
473 | # tags_reset: Tags reset | ||
474 | # entries_reset: Entries reset | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | entry_already_saved: 'Article ja salvargardat lo %date%' | 477 | entry_already_saved: 'Article ja salvargardat lo %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml index 6f22f90d..b05a9dfd 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml | |||
@@ -93,6 +93,13 @@ config: | |||
93 | description: Jeżeli usuniesz swoje konto, wszystkie twoje artykuły, tagi, adnotacje, oraz konto zostaną trwale usunięte (operacja jest NIEODWRACALNA). Następnie zostaniesz wylogowany. | 93 | description: Jeżeli usuniesz swoje konto, wszystkie twoje artykuły, tagi, adnotacje, oraz konto zostaną trwale usunięte (operacja jest NIEODWRACALNA). Następnie zostaniesz wylogowany. |
94 | confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć) | 94 | confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć) |
95 | button: Usuń moje konto | 95 | button: Usuń moje konto |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Stare hasło' | 104 | old_password_label: 'Stare hasło' |
98 | new_password_label: 'Nowe hasło' | 105 | new_password_label: 'Nowe hasło' |
@@ -462,6 +469,9 @@ flashes: | |||
462 | tagging_rules_deleted: 'Reguła tagowania usunięta' | 469 | tagging_rules_deleted: 'Reguła tagowania usunięta' |
463 | user_added: 'Użytkownik "%username%" dodany' | 470 | user_added: 'Użytkownik "%username%" dodany' |
464 | rss_token_updated: 'Token kanału RSS zaktualizowany' | 471 | rss_token_updated: 'Token kanału RSS zaktualizowany' |
472 | # annotations_reset: Annotations reset | ||
473 | # tags_reset: Tags reset | ||
474 | # entries_reset: Entries reset | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | entry_already_saved: 'Wpis już został dodany %date%' | 477 | entry_already_saved: 'Wpis już został dodany %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml index 29db9c3e..571452c0 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'E-mail' | 89 | email_label: 'E-mail' |
90 | # twoFactorAuthentication_label: 'Two factor authentication' | 90 | # twoFactorAuthentication_label: 'Two factor authentication' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Parola veche' | 104 | old_password_label: 'Parola veche' |
98 | new_password_label: 'Parola nouă' | 105 | new_password_label: 'Parola nouă' |
@@ -462,6 +469,9 @@ flashes: | |||
462 | # tagging_rules_deleted: 'Tagging rule deleted' | 469 | # tagging_rules_deleted: 'Tagging rule deleted' |
463 | # user_added: 'User "%username%" added' | 470 | # user_added: 'User "%username%" added' |
464 | # rss_token_updated: 'RSS token updated' | 471 | # rss_token_updated: 'RSS token updated' |
472 | # annotations_reset: Annotations reset | ||
473 | # tags_reset: Tags reset | ||
474 | # entries_reset: Entries reset | ||
465 | entry: | 475 | entry: |
466 | notice: | 476 | notice: |
467 | # entry_already_saved: 'Entry already saved on %date%' | 477 | # entry_already_saved: 'Entry already saved on %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml index 41e8e576..8e429653 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml | |||
@@ -89,10 +89,17 @@ config: | |||
89 | email_label: 'E-posta' | 89 | email_label: 'E-posta' |
90 | twoFactorAuthentication_label: 'İki adımlı doğrulama' | 90 | twoFactorAuthentication_label: 'İki adımlı doğrulama' |
91 | delete: | 91 | delete: |
92 | # title: Delete my account (danger zone !) | 92 | # title: Delete my account (a.k.a danger zone) |
93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | 93 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. |
94 | # confirm: Are you really sure? (it can't be UNDONE) | 94 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) |
95 | # button: Delete my account | 95 | # button: Delete my account |
96 | reset: | ||
97 | # title: Reset area (a.k.a danger zone) | ||
98 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
99 | # annotations: Remove ALL annotations | ||
100 | # tags: Remove ALL tags | ||
101 | # entries: Remove ALL entries | ||
102 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
96 | form_password: | 103 | form_password: |
97 | old_password_label: 'Eski şifre' | 104 | old_password_label: 'Eski şifre' |
98 | new_password_label: 'Yeni şifre' | 105 | new_password_label: 'Yeni şifre' |
@@ -461,6 +468,9 @@ flashes: | |||
461 | tagging_rules_deleted: 'Tagging rule deleted' | 468 | tagging_rules_deleted: 'Tagging rule deleted' |
462 | user_added: 'User "%username%" added' | 469 | user_added: 'User "%username%" added' |
463 | rss_token_updated: 'RSS token updated' | 470 | rss_token_updated: 'RSS token updated' |
471 | # annotations_reset: Annotations reset | ||
472 | # tags_reset: Tags reset | ||
473 | # entries_reset: Entries reset | ||
464 | entry: | 474 | entry: |
465 | notice: | 475 | notice: |
466 | entry_already_saved: 'Entry already saved on %date%' | 476 | entry_already_saved: 'Entry already saved on %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig index 54508b6d..455d0295 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig | |||
@@ -146,6 +146,28 @@ | |||
146 | </fieldset> | 146 | </fieldset> |
147 | {% endif %} | 147 | {% endif %} |
148 | 148 | ||
149 | <h2>{{ 'config.reset.title'|trans }}</h2> | ||
150 | <fieldset class="w500p inline"> | ||
151 | <p>{{ 'config.reset.description'|trans }}</p> | ||
152 | <ul> | ||
153 | <li> | ||
154 | <a href="{{ path('config_reset', { type: 'annotations'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
155 | {{ 'config.reset.annotations'|trans }} | ||
156 | </a> | ||
157 | </li> | ||
158 | <li> | ||
159 | <a href="{{ path('config_reset', { type: 'tags'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
160 | {{ 'config.reset.tags'|trans }} | ||
161 | </a> | ||
162 | </li> | ||
163 | <li> | ||
164 | <a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
165 | {{ 'config.reset.entries'|trans }} | ||
166 | </a> | ||
167 | </li> | ||
168 | </ul> | ||
169 | </fieldset> | ||
170 | |||
149 | {{ form_widget(form.user._token) }} | 171 | {{ form_widget(form.user._token) }} |
150 | {{ form_widget(form.user.save) }} | 172 | {{ form_widget(form.user.save) }} |
151 | </form> | 173 | </form> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig index 8434508d..79826e0f 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig | |||
@@ -168,6 +168,22 @@ | |||
168 | {{ form_widget(form.user._token) }} | 168 | {{ form_widget(form.user._token) }} |
169 | </form> | 169 | </form> |
170 | 170 | ||
171 | <br /><hr /><br /> | ||
172 | |||
173 | <div class="row"> | ||
174 | <h5>{{ 'config.reset.title'|trans }}</h5> | ||
175 | <p>{{ 'config.reset.description'|trans }}</p> | ||
176 | <a href="{{ path('config_reset', { type: 'annotations'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
177 | {{ 'config.reset.annotations'|trans }} | ||
178 | </a> | ||
179 | <a href="{{ path('config_reset', { type: 'tags'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
180 | {{ 'config.reset.tags'|trans }} | ||
181 | </a> | ||
182 | <a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
183 | {{ 'config.reset.entries'|trans }} | ||
184 | </a> | ||
185 | </div> | ||
186 | |||
171 | {% if enabled_users > 1 %} | 187 | {% if enabled_users > 1 %} |
172 | <br /><hr /><br /> | 188 | <br /><hr /><br /> |
173 | 189 | ||
diff --git a/src/Wallabag/CoreBundle/Subscriber/SQLiteCascadeDeleteSubscriber.php b/src/Wallabag/CoreBundle/Subscriber/SQLiteCascadeDeleteSubscriber.php new file mode 100644 index 00000000..f7210bd3 --- /dev/null +++ b/src/Wallabag/CoreBundle/Subscriber/SQLiteCascadeDeleteSubscriber.php | |||
@@ -0,0 +1,70 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Subscriber; | ||
4 | |||
5 | use Doctrine\Common\EventSubscriber; | ||
6 | use Doctrine\ORM\Event\LifecycleEventArgs; | ||
7 | use Wallabag\CoreBundle\Entity\Entry; | ||
8 | use Doctrine\Bundle\DoctrineBundle\Registry; | ||
9 | |||
10 | /** | ||
11 | * SQLite doesn't care about cascading remove, so we need to manually remove associated stuf for an Entry. | ||
12 | * Foreign Key Support can be enabled by running `PRAGMA foreign_keys = ON;` at runtime (AT RUNTIME !). | ||
13 | * But it needs a compilation flag that not all SQLite instance has ... | ||
14 | * | ||
15 | * @see https://www.sqlite.org/foreignkeys.html#fk_enable | ||
16 | */ | ||
17 | class SQLiteCascadeDeleteSubscriber implements EventSubscriber | ||
18 | { | ||
19 | private $doctrine; | ||
20 | |||
21 | /** | ||
22 | * @param \Doctrine\Bundle\DoctrineBundle\Registry $doctrine | ||
23 | */ | ||
24 | public function __construct(Registry $doctrine) | ||
25 | { | ||
26 | $this->doctrine = $doctrine; | ||
27 | } | ||
28 | |||
29 | /** | ||
30 | * @return array | ||
31 | */ | ||
32 | public function getSubscribedEvents() | ||
33 | { | ||
34 | return [ | ||
35 | 'preRemove', | ||
36 | ]; | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * We removed everything related to the upcoming removed entry because SQLite can't handle it on it own. | ||
41 | * We do it in the preRemove, because we can't retrieve tags in the postRemove (because the entry id is gone). | ||
42 | * | ||
43 | * @param LifecycleEventArgs $args | ||
44 | */ | ||
45 | public function preRemove(LifecycleEventArgs $args) | ||
46 | { | ||
47 | $entity = $args->getEntity(); | ||
48 | |||
49 | if (!$this->doctrine->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver || | ||
50 | !$entity instanceof Entry) { | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | $em = $this->doctrine->getManager(); | ||
55 | |||
56 | if (null !== $entity->getTags()) { | ||
57 | foreach ($entity->getTags() as $tag) { | ||
58 | $entity->removeTag($tag); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | if (null !== $entity->getAnnotations()) { | ||
63 | foreach ($entity->getAnnotations() as $annotation) { | ||
64 | $em->remove($annotation); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | $em->flush(); | ||
69 | } | ||
70 | } | ||
diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml index eb9c8e67..8062e53f 100644 --- a/src/Wallabag/UserBundle/Resources/config/services.yml +++ b/src/Wallabag/UserBundle/Resources/config/services.yml | |||
@@ -21,7 +21,7 @@ services: | |||
21 | arguments: | 21 | arguments: |
22 | - WallabagUserBundle:User | 22 | - WallabagUserBundle:User |
23 | 23 | ||
24 | wallabag_user.create_config: | 24 | wallabag_user.listener.create_config: |
25 | class: Wallabag\UserBundle\EventListener\CreateConfigListener | 25 | class: Wallabag\UserBundle\EventListener\CreateConfigListener |
26 | arguments: | 26 | arguments: |
27 | - "@doctrine.orm.entity_manager" | 27 | - "@doctrine.orm.entity_manager" |
diff --git a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php index 5faa0130..8d0644d1 100644 --- a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php | |||
@@ -5,6 +5,9 @@ namespace Tests\Wallabag\CoreBundle\Controller; | |||
5 | use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; | 5 | use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; |
6 | use Wallabag\CoreBundle\Entity\Config; | 6 | use Wallabag\CoreBundle\Entity\Config; |
7 | use Wallabag\UserBundle\Entity\User; | 7 | use Wallabag\UserBundle\Entity\User; |
8 | use Wallabag\CoreBundle\Entity\Entry; | ||
9 | use Wallabag\CoreBundle\Entity\Tag; | ||
10 | use Wallabag\AnnotationBundle\Entity\Annotation; | ||
8 | 11 | ||
9 | class ConfigControllerTest extends WallabagCoreTestCase | 12 | class ConfigControllerTest extends WallabagCoreTestCase |
10 | { | 13 | { |
@@ -690,4 +693,146 @@ class ConfigControllerTest extends WallabagCoreTestCase | |||
690 | 693 | ||
691 | $this->assertEmpty($entries); | 694 | $this->assertEmpty($entries); |
692 | } | 695 | } |
696 | |||
697 | public function testReset() | ||
698 | { | ||
699 | $this->logInAs('empty'); | ||
700 | $client = $this->getClient(); | ||
701 | |||
702 | $em = $client->getContainer()->get('doctrine.orm.entity_manager'); | ||
703 | |||
704 | $user = static::$kernel->getContainer()->get('security.token_storage')->getToken()->getUser(); | ||
705 | |||
706 | $tag = new Tag(); | ||
707 | $tag->setLabel('super'); | ||
708 | $em->persist($tag); | ||
709 | |||
710 | $entry = new Entry($user); | ||
711 | $entry->setUrl('http://www.lemonde.fr/europe/article/2016/10/01/pour-le-psoe-chaque-election-s-est-transformee-en-une-agonie_5006476_3214.html'); | ||
712 | $entry->setContent('Youhou'); | ||
713 | $entry->setTitle('Youhou'); | ||
714 | $entry->addTag($tag); | ||
715 | $em->persist($entry); | ||
716 | |||
717 | $entry2 = new Entry($user); | ||
718 | $entry2->setUrl('http://www.lemonde.de/europe/article/2016/10/01/pour-le-psoe-chaque-election-s-est-transformee-en-une-agonie_5006476_3214.html'); | ||
719 | $entry2->setContent('Youhou'); | ||
720 | $entry2->setTitle('Youhou'); | ||
721 | $entry2->addTag($tag); | ||
722 | $em->persist($entry2); | ||
723 | |||
724 | $annotation = new Annotation($user); | ||
725 | $annotation->setText('annotated'); | ||
726 | $annotation->setQuote('annotated'); | ||
727 | $annotation->setRanges([]); | ||
728 | $annotation->setEntry($entry); | ||
729 | $em->persist($annotation); | ||
730 | |||
731 | $em->flush(); | ||
732 | |||
733 | // reset annotations | ||
734 | $crawler = $client->request('GET', '/config#set3'); | ||
735 | |||
736 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
737 | |||
738 | $crawler = $client->click($crawler->selectLink('config.reset.annotations')->link()); | ||
739 | |||
740 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
741 | $this->assertContains('flashes.config.notice.annotations_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); | ||
742 | |||
743 | $annotationsReset = $em | ||
744 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
745 | ->findAnnotationsByPageId($entry->getId(), $user->getId()); | ||
746 | |||
747 | $this->assertEmpty($annotationsReset, 'Annotations were reset'); | ||
748 | |||
749 | // reset tags | ||
750 | $crawler = $client->request('GET', '/config#set3'); | ||
751 | |||
752 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
753 | |||
754 | $crawler = $client->click($crawler->selectLink('config.reset.tags')->link()); | ||
755 | |||
756 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
757 | $this->assertContains('flashes.config.notice.tags_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); | ||
758 | |||
759 | $tagReset = $em | ||
760 | ->getRepository('WallabagCoreBundle:Tag') | ||
761 | ->countAllTags($user->getId()); | ||
762 | |||
763 | $this->assertEquals(0, $tagReset, 'Tags were reset'); | ||
764 | |||
765 | // reset entries | ||
766 | $crawler = $client->request('GET', '/config#set3'); | ||
767 | |||
768 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
769 | |||
770 | $crawler = $client->click($crawler->selectLink('config.reset.entries')->link()); | ||
771 | |||
772 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
773 | $this->assertContains('flashes.config.notice.entries_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); | ||
774 | |||
775 | $entryReset = $em | ||
776 | ->getRepository('WallabagCoreBundle:Entry') | ||
777 | ->countAllEntriesByUsername($user->getId()); | ||
778 | |||
779 | $this->assertEquals(0, $entryReset, 'Entries were reset'); | ||
780 | } | ||
781 | |||
782 | public function testResetEntriesCascade() | ||
783 | { | ||
784 | $this->logInAs('empty'); | ||
785 | $client = $this->getClient(); | ||
786 | |||
787 | $em = $client->getContainer()->get('doctrine.orm.entity_manager'); | ||
788 | |||
789 | $user = static::$kernel->getContainer()->get('security.token_storage')->getToken()->getUser(); | ||
790 | |||
791 | $tag = new Tag(); | ||
792 | $tag->setLabel('super'); | ||
793 | $em->persist($tag); | ||
794 | |||
795 | $entry = new Entry($user); | ||
796 | $entry->setUrl('http://www.lemonde.fr/europe/article/2016/10/01/pour-le-psoe-chaque-election-s-est-transformee-en-une-agonie_5006476_3214.html'); | ||
797 | $entry->setContent('Youhou'); | ||
798 | $entry->setTitle('Youhou'); | ||
799 | $entry->addTag($tag); | ||
800 | $em->persist($entry); | ||
801 | |||
802 | $annotation = new Annotation($user); | ||
803 | $annotation->setText('annotated'); | ||
804 | $annotation->setQuote('annotated'); | ||
805 | $annotation->setRanges([]); | ||
806 | $annotation->setEntry($entry); | ||
807 | $em->persist($annotation); | ||
808 | |||
809 | $em->flush(); | ||
810 | |||
811 | $crawler = $client->request('GET', '/config#set3'); | ||
812 | |||
813 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
814 | |||
815 | $crawler = $client->click($crawler->selectLink('config.reset.entries')->link()); | ||
816 | |||
817 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
818 | $this->assertContains('flashes.config.notice.entries_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); | ||
819 | |||
820 | $entryReset = $em | ||
821 | ->getRepository('WallabagCoreBundle:Entry') | ||
822 | ->countAllEntriesByUsername($user->getId()); | ||
823 | |||
824 | $this->assertEquals(0, $entryReset, 'Entries were reset'); | ||
825 | |||
826 | $tagReset = $em | ||
827 | ->getRepository('WallabagCoreBundle:Tag') | ||
828 | ->countAllTags($user->getId()); | ||
829 | |||
830 | $this->assertEquals(0, $tagReset, 'Tags were reset'); | ||
831 | |||
832 | $annotationsReset = $em | ||
833 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
834 | ->findAnnotationsByPageId($entry->getId(), $user->getId()); | ||
835 | |||
836 | $this->assertEmpty($annotationsReset, 'Annotations were reset'); | ||
837 | } | ||
693 | } | 838 | } |