aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xMakefile4
-rw-r--r--README.md2
-rw-r--r--app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml4
-rw-r--r--src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php2
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php1
-rw-r--r--src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php21
-rw-r--r--src/Wallabag/CoreBundle/Command/ExportCommand.php11
-rw-r--r--src/Wallabag/CoreBundle/Command/InstallCommand.php87
-rw-r--r--src/Wallabag/CoreBundle/Command/ListUserCommand.php61
-rw-r--r--src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php90
-rw-r--r--src/Wallabag/CoreBundle/Command/ShowUserCommand.php10
-rw-r--r--src/Wallabag/CoreBundle/Command/TagAllCommand.php14
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php1
-rw-r--r--src/Wallabag/CoreBundle/Controller/TagController.php21
-rw-r--r--src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php3
-rw-r--r--src/Wallabag/CoreBundle/Helper/EntriesExport.php4
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php48
-rw-r--r--src/Wallabag/CoreBundle/Repository/TagRepository.php22
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml75
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml27
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig6
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig2
-rw-r--r--src/Wallabag/ImportBundle/Controller/WallabagController.php2
-rw-r--r--src/Wallabag/ImportBundle/Import/BrowserImport.php3
-rw-r--r--src/Wallabag/UserBundle/Repository/UserRepository.php15
-rw-r--r--src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml6
-rw-r--r--tests/Wallabag/CoreBundle/Command/ExportCommandTest.php3
-rw-r--r--tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php75
-rw-r--r--tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php115
-rw-r--r--tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php8
-rw-r--r--tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php3
41 files changed, 568 insertions, 188 deletions
diff --git a/Makefile b/Makefile
index b3335261..ffbe102a 100755
--- a/Makefile
+++ b/Makefile
@@ -23,8 +23,8 @@ dev: ## Install the latest dev version
23run: ## Run the wallabag built-in server 23run: ## Run the wallabag built-in server
24 @php bin/console server:run --env=$(ENV) 24 @php bin/console server:run --env=$(ENV)
25 25
26build: ## Run grunt 26build: ## Run webpack
27 @grunt 27 @npm run build:$(ENV)
28 28
29test: ## Launch wallabag testsuite 29test: ## Launch wallabag testsuite
30 @ant prepare && bin/simple-phpunit -v 30 @ant prepare && bin/simple-phpunit -v
diff --git a/README.md b/README.md
index 1b20e5d1..ebcdc564 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
3[![Gitter](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/wallabag/wallabag) 3[![Gitter](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/wallabag/wallabag)
4 4
5# What is wallabag? 5# What is wallabag?
6wallabag is a self hostable application allowing you to not miss any content anymore. 6wallabag is a self-hostable PHP application allowing you to not miss any content anymore.
7Click, save and read it when you can. It extracts content so that you can read it when you have time. 7Click, save and read it when you can. It extracts content so that you can read it when you have time.
8 8
9More information on our website: [wallabag.org](https://wallabag.org). 9More information on our website: [wallabag.org](https://wallabag.org).
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
index 66d9ae26..0861d59c 100644
--- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
+++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
@@ -9,7 +9,7 @@ export_csv: Activar l'expòrt CSV
9export_json: Activar l'expòrt JSON 9export_json: Activar l'expòrt JSON
10export_txt: Activar l'expòrt TXT 10export_txt: Activar l'expòrt TXT
11export_xml: Activar l'expòrt XML 11export_xml: Activar l'expòrt XML
12import_with_rabbitmq: Activar Enable RabbitMQ per importar de donadas de manièra asincròna 12import_with_rabbitmq: Activar RabbitMQ per importar de donadas de manièra asincròna
13import_with_redis: Activar Redis per importar de donadas de manièra asincròna 13import_with_redis: Activar Redis per importar de donadas de manièra asincròna
14shaarli_url: URL de Shaarli, se lo servici Shaarli es activat 14shaarli_url: URL de Shaarli, se lo servici Shaarli es activat
15share_diaspora: Activar lo partatge cap a Diaspora 15share_diaspora: Activar lo partatge cap a Diaspora
@@ -33,4 +33,4 @@ demo_mode_username: "Utilizaire de la demostracion"
33share_public: Autorizar una URL publica pels articles 33share_public: Autorizar una URL publica pels articles
34download_images_enabled: Telecargar los imatges en local 34download_images_enabled: Telecargar los imatges en local
35restricted_access: Activar l'autenticacion pels sites amb peatge 35restricted_access: Activar l'autenticacion pels sites amb peatge
36# api_user_registration: Enable user to be registered using the API 36api_user_registration: Autorizar los utilizaires a se marcar amb l'API
diff --git a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php
index 014c29b6..b44f7e64 100644
--- a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php
+++ b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php
@@ -3,6 +3,8 @@
3namespace Wallabag\AnnotationBundle\Repository; 3namespace Wallabag\AnnotationBundle\Repository;
4 4
5use Doctrine\ORM\EntityRepository; 5use Doctrine\ORM\EntityRepository;
6use Doctrine\ORM\QueryBuilder;
7use Wallabag\AnnotationBundle\Entity\Annotation;
6 8
7/** 9/**
8 * AnnotationRepository. 10 * AnnotationRepository.
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index 9277e1a1..bc1b6f92 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -8,6 +8,7 @@ use JMS\Serializer\SerializationContext;
8use Nelmio\ApiDocBundle\Annotation\ApiDoc; 8use Nelmio\ApiDocBundle\Annotation\ApiDoc;
9use Symfony\Component\HttpFoundation\JsonResponse; 9use Symfony\Component\HttpFoundation\JsonResponse;
10use Symfony\Component\HttpFoundation\Request; 10use Symfony\Component\HttpFoundation\Request;
11use Symfony\Component\HttpFoundation\Response;
11use Symfony\Component\HttpKernel\Exception\HttpException; 12use Symfony\Component\HttpKernel\Exception\HttpException;
12use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 13use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
13use Wallabag\CoreBundle\Entity\Entry; 14use Wallabag\CoreBundle\Entity\Entry;
diff --git a/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php
index b4aa4e47..b58909db 100644
--- a/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php
+++ b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php
@@ -7,13 +7,14 @@ use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
7use Symfony\Component\Console\Input\InputArgument; 7use Symfony\Component\Console\Input\InputArgument;
8use Symfony\Component\Console\Input\InputInterface; 8use Symfony\Component\Console\Input\InputInterface;
9use Symfony\Component\Console\Output\OutputInterface; 9use Symfony\Component\Console\Output\OutputInterface;
10use Symfony\Component\Console\Style\SymfonyStyle;
10use Wallabag\CoreBundle\Entity\Entry; 11use Wallabag\CoreBundle\Entity\Entry;
11use Wallabag\UserBundle\Entity\User; 12use Wallabag\UserBundle\Entity\User;
12 13
13class CleanDuplicatesCommand extends ContainerAwareCommand 14class CleanDuplicatesCommand extends ContainerAwareCommand
14{ 15{
15 /** @var OutputInterface */ 16 /** @var SymfonyStyle */
16 protected $output; 17 protected $io;
17 18
18 protected $duplicates = 0; 19 protected $duplicates = 0;
19 20
@@ -32,7 +33,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
32 33
33 protected function execute(InputInterface $input, OutputInterface $output) 34 protected function execute(InputInterface $input, OutputInterface $output)
34 { 35 {
35 $this->output = $output; 36 $this->io = new SymfonyStyle($input, $output);
36 37
37 $username = $input->getArgument('username'); 38 $username = $input->getArgument('username');
38 39
@@ -41,20 +42,22 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
41 $user = $this->getUser($username); 42 $user = $this->getUser($username);
42 $this->cleanDuplicates($user); 43 $this->cleanDuplicates($user);
43 } catch (NoResultException $e) { 44 } catch (NoResultException $e) {
44 $output->writeln(sprintf('<error>User "%s" not found.</error>', $username)); 45 $this->io->error(sprintf('User "%s" not found.', $username));
45 46
46 return 1; 47 return 1;
47 } 48 }
49
50 $this->io->success('Finished cleaning.');
48 } else { 51 } else {
49 $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll(); 52 $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll();
50 53
51 $output->writeln(sprintf('Cleaning through %d user accounts', count($users))); 54 $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', count($users)));
52 55
53 foreach ($users as $user) { 56 foreach ($users as $user) {
54 $output->writeln(sprintf('Processing user %s', $user->getUsername())); 57 $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername()));
55 $this->cleanDuplicates($user); 58 $this->cleanDuplicates($user);
56 } 59 }
57 $output->writeln(sprintf('Finished cleaning. %d duplicates found in total', $this->duplicates)); 60 $this->io->success(sprintf('Finished cleaning. %d duplicates found in total', $this->duplicates));
58 } 61 }
59 62
60 return 0; 63 return 0;
@@ -68,7 +71,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
68 $em = $this->getContainer()->get('doctrine.orm.entity_manager'); 71 $em = $this->getContainer()->get('doctrine.orm.entity_manager');
69 $repo = $this->getContainer()->get('wallabag_core.entry_repository'); 72 $repo = $this->getContainer()->get('wallabag_core.entry_repository');
70 73
71 $entries = $repo->getAllEntriesIdAndUrl($user->getId()); 74 $entries = $repo->findAllEntriesIdAndUrlByUserId($user->getId());
72 75
73 $duplicatesCount = 0; 76 $duplicatesCount = 0;
74 $urls = []; 77 $urls = [];
@@ -88,7 +91,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
88 91
89 $this->duplicates += $duplicatesCount; 92 $this->duplicates += $duplicatesCount;
90 93
91 $this->output->writeln(sprintf('Cleaned %d duplicates for user %s', $duplicatesCount, $user->getUserName())); 94 $this->io->text(sprintf('Cleaned <info>%d</info> duplicates for user <info>%s</info>', $duplicatesCount, $user->getUserName()));
92 } 95 }
93 96
94 private function similarUrl($url) 97 private function similarUrl($url)
diff --git a/src/Wallabag/CoreBundle/Command/ExportCommand.php b/src/Wallabag/CoreBundle/Command/ExportCommand.php
index 291926e4..b07087c8 100644
--- a/src/Wallabag/CoreBundle/Command/ExportCommand.php
+++ b/src/Wallabag/CoreBundle/Command/ExportCommand.php
@@ -7,6 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
7use Symfony\Component\Console\Input\InputArgument; 7use Symfony\Component\Console\Input\InputArgument;
8use Symfony\Component\Console\Input\InputInterface; 8use Symfony\Component\Console\Input\InputInterface;
9use Symfony\Component\Console\Output\OutputInterface; 9use Symfony\Component\Console\Output\OutputInterface;
10use Symfony\Component\Console\Style\SymfonyStyle;
10 11
11class ExportCommand extends ContainerAwareCommand 12class ExportCommand extends ContainerAwareCommand
12{ 13{
@@ -31,10 +32,12 @@ class ExportCommand extends ContainerAwareCommand
31 32
32 protected function execute(InputInterface $input, OutputInterface $output) 33 protected function execute(InputInterface $input, OutputInterface $output)
33 { 34 {
35 $io = new SymfonyStyle($input, $output);
36
34 try { 37 try {
35 $user = $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($input->getArgument('username')); 38 $user = $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($input->getArgument('username'));
36 } catch (NoResultException $e) { 39 } catch (NoResultException $e) {
37 $output->writeln(sprintf('<error>User "%s" not found.</error>', $input->getArgument('username'))); 40 $io->error(sprintf('User "%s" not found.', $input->getArgument('username')));
38 41
39 return 1; 42 return 1;
40 } 43 }
@@ -44,7 +47,7 @@ class ExportCommand extends ContainerAwareCommand
44 ->getQuery() 47 ->getQuery()
45 ->getResult(); 48 ->getResult();
46 49
47 $output->write(sprintf('Exporting %d entrie(s) for user « <comment>%s</comment> »... ', count($entries), $user->getUserName())); 50 $io->text(sprintf('Exporting <info>%d</info> entrie(s) for user <info>%s</info>...', count($entries), $user->getUserName()));
48 51
49 $filePath = $input->getArgument('filepath'); 52 $filePath = $input->getArgument('filepath');
50 53
@@ -60,12 +63,12 @@ class ExportCommand extends ContainerAwareCommand
60 ->exportJsonData(); 63 ->exportJsonData();
61 file_put_contents($filePath, $data); 64 file_put_contents($filePath, $data);
62 } catch (\InvalidArgumentException $e) { 65 } catch (\InvalidArgumentException $e) {
63 $output->writeln(sprintf('<error>Error: "%s"</error>', $e->getMessage())); 66 $io->error(sprintf('Error: "%s"', $e->getMessage()));
64 67
65 return 1; 68 return 1;
66 } 69 }
67 70
68 $output->writeln('<info>Done.</info>'); 71 $io->success('Done.');
69 72
70 return 0; 73 return 0;
71 } 74 }
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index c7809053..877dbfa2 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -6,14 +6,13 @@ use Craue\ConfigBundle\Entity\Setting;
6use FOS\UserBundle\Event\UserEvent; 6use FOS\UserBundle\Event\UserEvent;
7use FOS\UserBundle\FOSUserEvents; 7use FOS\UserBundle\FOSUserEvents;
8use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; 8use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
9use Symfony\Component\Console\Helper\Table;
10use Symfony\Component\Console\Input\ArrayInput; 9use Symfony\Component\Console\Input\ArrayInput;
11use Symfony\Component\Console\Input\InputInterface; 10use Symfony\Component\Console\Input\InputInterface;
12use Symfony\Component\Console\Input\InputOption; 11use Symfony\Component\Console\Input\InputOption;
13use Symfony\Component\Console\Output\BufferedOutput; 12use Symfony\Component\Console\Output\BufferedOutput;
14use Symfony\Component\Console\Output\OutputInterface; 13use Symfony\Component\Console\Output\OutputInterface;
15use Symfony\Component\Console\Question\ConfirmationQuestion;
16use Symfony\Component\Console\Question\Question; 14use Symfony\Component\Console\Question\Question;
15use Symfony\Component\Console\Style\SymfonyStyle;
17 16
18class InstallCommand extends ContainerAwareCommand 17class InstallCommand extends ContainerAwareCommand
19{ 18{
@@ -23,9 +22,9 @@ class InstallCommand extends ContainerAwareCommand
23 protected $defaultInput; 22 protected $defaultInput;
24 23
25 /** 24 /**
26 * @var OutputInterface 25 * @var SymfonyStyle
27 */ 26 */
28 protected $defaultOutput; 27 protected $io;
29 28
30 /** 29 /**
31 * @var array 30 * @var array
@@ -52,10 +51,10 @@ class InstallCommand extends ContainerAwareCommand
52 protected function execute(InputInterface $input, OutputInterface $output) 51 protected function execute(InputInterface $input, OutputInterface $output)
53 { 52 {
54 $this->defaultInput = $input; 53 $this->defaultInput = $input;
55 $this->defaultOutput = $output;
56 54
57 $output->writeln('<info>Installing wallabag...</info>'); 55 $this->io = new SymfonyStyle($input, $output);
58 $output->writeln(''); 56
57 $this->io->title('Wallabag installer');
59 58
60 $this 59 $this
61 ->checkRequirements() 60 ->checkRequirements()
@@ -65,13 +64,14 @@ class InstallCommand extends ContainerAwareCommand
65 ->runMigrations() 64 ->runMigrations()
66 ; 65 ;
67 66
68 $output->writeln('<info>wallabag has been successfully installed.</info>'); 67 $this->io->success('Wallabag has been successfully installed.');
69 $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>'); 68 $this->io->note('Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000');
70 } 69 }
71 70
72 protected function checkRequirements() 71 protected function checkRequirements()
73 { 72 {
74 $this->defaultOutput->writeln('<info><comment>Step 1 of 5.</comment> Checking system requirements.</info>'); 73 $this->io->section('Step 1 of 5: Checking system requirements.');
74
75 $doctrineManager = $this->getContainer()->get('doctrine')->getManager(); 75 $doctrineManager = $this->getContainer()->get('doctrine')->getManager();
76 76
77 $rows = []; 77 $rows = [];
@@ -156,30 +156,24 @@ class InstallCommand extends ContainerAwareCommand
156 $rows[] = [$label, $status, $help]; 156 $rows[] = [$label, $status, $help];
157 } 157 }
158 158
159 $table = new Table($this->defaultOutput); 159 $this->io->table(['Checked', 'Status', 'Recommendation'], $rows);
160 $table
161 ->setHeaders(['Checked', 'Status', 'Recommendation'])
162 ->setRows($rows)
163 ->render();
164 160
165 if (!$fulfilled) { 161 if (!$fulfilled) {
166 throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); 162 throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.');
167 } 163 }
168 164
169 $this->defaultOutput->writeln('<info>Success! Your system can run wallabag properly.</info>'); 165 $this->io->success('Success! Your system can run wallabag properly.');
170
171 $this->defaultOutput->writeln('');
172 166
173 return $this; 167 return $this;
174 } 168 }
175 169
176 protected function setupDatabase() 170 protected function setupDatabase()
177 { 171 {
178 $this->defaultOutput->writeln('<info><comment>Step 2 of 5.</comment> Setting up database.</info>'); 172 $this->io->section('Step 2 of 5: Setting up database.');
179 173
180 // user want to reset everything? Don't care about what is already here 174 // user want to reset everything? Don't care about what is already here
181 if (true === $this->defaultInput->getOption('reset')) { 175 if (true === $this->defaultInput->getOption('reset')) {
182 $this->defaultOutput->writeln('Dropping database, creating database and schema, clearing the cache'); 176 $this->io->text('Dropping database, creating database and schema, clearing the cache');
183 177
184 $this 178 $this
185 ->runCommand('doctrine:database:drop', ['--force' => true]) 179 ->runCommand('doctrine:database:drop', ['--force' => true])
@@ -188,13 +182,13 @@ class InstallCommand extends ContainerAwareCommand
188 ->runCommand('cache:clear') 182 ->runCommand('cache:clear')
189 ; 183 ;
190 184
191 $this->defaultOutput->writeln(''); 185 $this->io->newLine();
192 186
193 return $this; 187 return $this;
194 } 188 }
195 189
196 if (!$this->isDatabasePresent()) { 190 if (!$this->isDatabasePresent()) {
197 $this->defaultOutput->writeln('Creating database and schema, clearing the cache'); 191 $this->io->text('Creating database and schema, clearing the cache');
198 192
199 $this 193 $this
200 ->runCommand('doctrine:database:create') 194 ->runCommand('doctrine:database:create')
@@ -202,16 +196,13 @@ class InstallCommand extends ContainerAwareCommand
202 ->runCommand('cache:clear') 196 ->runCommand('cache:clear')
203 ; 197 ;
204 198
205 $this->defaultOutput->writeln(''); 199 $this->io->newLine();
206 200
207 return $this; 201 return $this;
208 } 202 }
209 203
210 $questionHelper = $this->getHelper('question'); 204 if ($this->io->confirm('It appears that your database already exists. Would you like to reset it?', false)) {
211 $question = new ConfirmationQuestion('It appears that your database already exists. Would you like to reset it? (y/N)', false); 205 $this->io->text('Dropping database, creating database and schema...');
212
213 if ($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question)) {
214 $this->defaultOutput->writeln('Dropping database, creating database and schema');
215 206
216 $this 207 $this
217 ->runCommand('doctrine:database:drop', ['--force' => true]) 208 ->runCommand('doctrine:database:drop', ['--force' => true])
@@ -219,9 +210,8 @@ class InstallCommand extends ContainerAwareCommand
219 ->runCommand('doctrine:schema:create') 210 ->runCommand('doctrine:schema:create')
220 ; 211 ;
221 } elseif ($this->isSchemaPresent()) { 212 } elseif ($this->isSchemaPresent()) {
222 $question = new ConfirmationQuestion('Seems like your database contains schema. Do you want to reset it? (y/N)', false); 213 if ($this->io->confirm('Seems like your database contains schema. Do you want to reset it?', false)) {
223 if ($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question)) { 214 $this->io->text('Dropping schema and creating schema...');
224 $this->defaultOutput->writeln('Dropping schema and creating schema');
225 215
226 $this 216 $this
227 ->runCommand('doctrine:schema:drop', ['--force' => true]) 217 ->runCommand('doctrine:schema:drop', ['--force' => true])
@@ -229,29 +219,27 @@ class InstallCommand extends ContainerAwareCommand
229 ; 219 ;
230 } 220 }
231 } else { 221 } else {
232 $this->defaultOutput->writeln('Creating schema'); 222 $this->io->text('Creating schema...');
233 223
234 $this 224 $this
235 ->runCommand('doctrine:schema:create') 225 ->runCommand('doctrine:schema:create')
236 ; 226 ;
237 } 227 }
238 228
239 $this->defaultOutput->writeln('Clearing the cache'); 229 $this->io->text('Clearing the cache...');
240 $this->runCommand('cache:clear'); 230 $this->runCommand('cache:clear');
241 231
242 $this->defaultOutput->writeln(''); 232 $this->io->newLine();
233 $this->io->text('<info>Database successfully setup.</info>');
243 234
244 return $this; 235 return $this;
245 } 236 }
246 237
247 protected function setupAdmin() 238 protected function setupAdmin()
248 { 239 {
249 $this->defaultOutput->writeln('<info><comment>Step 3 of 5.</comment> Administration setup.</info>'); 240 $this->io->section('Step 3 of 5: Administration setup.');
250
251 $questionHelper = $this->getHelperSet()->get('question');
252 $question = new ConfirmationQuestion('Would you like to create a new admin user (recommended) ? (Y/n)', true);
253 241
254 if (!$questionHelper->ask($this->defaultInput, $this->defaultOutput, $question)) { 242 if (!$this->io->confirm('Would you like to create a new admin user (recommended)?', true)) {
255 return $this; 243 return $this;
256 } 244 }
257 245
@@ -260,14 +248,13 @@ class InstallCommand extends ContainerAwareCommand
260 $userManager = $this->getContainer()->get('fos_user.user_manager'); 248 $userManager = $this->getContainer()->get('fos_user.user_manager');
261 $user = $userManager->createUser(); 249 $user = $userManager->createUser();
262 250
263 $question = new Question('Username (default: wallabag) :', 'wallabag'); 251 $user->setUsername($this->io->ask('Username', 'wallabag'));
264 $user->setUsername($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question));
265 252
266 $question = new Question('Password (default: wallabag) :', 'wallabag'); 253 $question = new Question('Password', 'wallabag');
267 $user->setPlainPassword($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question)); 254 $question->setHidden(true);
255 $user->setPlainPassword($this->io->askQuestion($question));
268 256
269 $question = new Question('Email:', ''); 257 $user->setEmail($this->io->ask('Email', ''));
270 $user->setEmail($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question));
271 258
272 $user->setEnabled(true); 259 $user->setEnabled(true);
273 $user->addRole('ROLE_SUPER_ADMIN'); 260 $user->addRole('ROLE_SUPER_ADMIN');
@@ -278,14 +265,14 @@ class InstallCommand extends ContainerAwareCommand
278 $event = new UserEvent($user); 265 $event = new UserEvent($user);
279 $this->getContainer()->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); 266 $this->getContainer()->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event);
280 267
281 $this->defaultOutput->writeln(''); 268 $this->io->text('<info>Administration successfully setup.</info>');
282 269
283 return $this; 270 return $this;
284 } 271 }
285 272
286 protected function setupConfig() 273 protected function setupConfig()
287 { 274 {
288 $this->defaultOutput->writeln('<info><comment>Step 4 of 5.</comment> Config setup.</info>'); 275 $this->io->section('Step 4 of 5: Config setup.');
289 $em = $this->getContainer()->get('doctrine.orm.entity_manager'); 276 $em = $this->getContainer()->get('doctrine.orm.entity_manager');
290 277
291 // cleanup before insert new stuff 278 // cleanup before insert new stuff
@@ -301,18 +288,20 @@ class InstallCommand extends ContainerAwareCommand
301 288
302 $em->flush(); 289 $em->flush();
303 290
304 $this->defaultOutput->writeln(''); 291 $this->io->text('<info>Config successfully setup.</info>');
305 292
306 return $this; 293 return $this;
307 } 294 }
308 295
309 protected function runMigrations() 296 protected function runMigrations()
310 { 297 {
311 $this->defaultOutput->writeln('<info><comment>Step 5 of 5.</comment> Run migrations.</info>'); 298 $this->io->section('Step 5 of 5: Run migrations.');
312 299
313 $this 300 $this
314 ->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]); 301 ->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]);
315 302
303 $this->io->text('<info>Migrations successfully executed.</info>');
304
316 return $this; 305 return $this;
317 } 306 }
318 307
diff --git a/src/Wallabag/CoreBundle/Command/ListUserCommand.php b/src/Wallabag/CoreBundle/Command/ListUserCommand.php
new file mode 100644
index 00000000..20660d18
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Command/ListUserCommand.php
@@ -0,0 +1,61 @@
1<?php
2
3namespace Wallabag\CoreBundle\Command;
4
5use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
6use Symfony\Component\Console\Input\InputArgument;
7use Symfony\Component\Console\Input\InputInterface;
8use Symfony\Component\Console\Input\InputOption;
9use Symfony\Component\Console\Output\OutputInterface;
10use Symfony\Component\Console\Style\SymfonyStyle;
11
12class ListUserCommand extends ContainerAwareCommand
13{
14 protected function configure()
15 {
16 $this
17 ->setName('wallabag:user:list')
18 ->setDescription('List all users')
19 ->setHelp('This command list all existing users')
20 ->addArgument('search', InputArgument::OPTIONAL, 'Filter list by given search term')
21 ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Max number of displayed users', 100)
22 ;
23 }
24
25 protected function execute(InputInterface $input, OutputInterface $output)
26 {
27 $io = new SymfonyStyle($input, $output);
28
29 $users = $this->getContainer()->get('wallabag_user.user_repository')
30 ->getQueryBuilderForSearch($input->getArgument('search'))
31 ->setMaxResults($input->getOption('limit'))
32 ->getQuery()
33 ->getResult();
34
35 $nbUsers = $this->getContainer()->get('wallabag_user.user_repository')
36 ->getSumUsers();
37
38 $rows = [];
39 foreach ($users as $user) {
40 $rows[] = [
41 $user->getUsername(),
42 $user->getEmail(),
43 $user->isEnabled() ? 'yes' : 'no',
44 $user->hasRole('ROLE_SUPER_ADMIN') || $user->hasRole('ROLE_ADMIN') ? 'yes' : 'no',
45 ];
46 }
47
48 $io->table(['username', 'email', 'is enabled?', 'is admin?'], $rows);
49
50 $io->success(
51 sprintf(
52 '%s/%s%s user(s) displayed.',
53 count($users),
54 $nbUsers,
55 $input->getArgument('search') === null ? '' : ' (filtered)'
56 )
57 );
58
59 return 0;
60 }
61}
diff --git a/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php b/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php
new file mode 100644
index 00000000..91998841
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php
@@ -0,0 +1,90 @@
1<?php
2
3namespace Wallabag\CoreBundle\Command;
4
5use Doctrine\ORM\NoResultException;
6use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
7use Symfony\Component\Console\Input\InputArgument;
8use Symfony\Component\Console\Input\InputInterface;
9use Symfony\Component\Console\Output\OutputInterface;
10use Symfony\Component\Console\Style\SymfonyStyle;
11use Wallabag\CoreBundle\Event\EntrySavedEvent;
12
13class ReloadEntryCommand extends ContainerAwareCommand
14{
15 protected function configure()
16 {
17 $this
18 ->setName('wallabag:entry:reload')
19 ->setDescription('Reload entries')
20 ->setHelp('This command reload entries')
21 ->addArgument('username', InputArgument::OPTIONAL, 'Reload entries only for the given user')
22 ;
23 }
24
25 protected function execute(InputInterface $input, OutputInterface $output)
26 {
27 $io = new SymfonyStyle($input, $output);
28
29 $userId = null;
30 if ($username = $input->getArgument('username')) {
31 try {
32 $userId = $this->getContainer()
33 ->get('wallabag_user.user_repository')
34 ->findOneByUserName($username)
35 ->getId();
36 } catch (NoResultException $e) {
37 $io->error(sprintf('User "%s" not found.', $username));
38
39 return 1;
40 }
41 }
42
43 $entryRepository = $this->getContainer()->get('wallabag_core.entry_repository');
44 $entryIds = $entryRepository->findAllEntriesIdByUserId($userId);
45
46 $nbEntries = count($entryIds);
47 if (!$nbEntries) {
48 $io->success('No entry to reload.');
49
50 return 0;
51 }
52
53 $io->note(
54 sprintf(
55 "You're going to reload %s entries. Depending on the number of entry to reload, this could be a very long process.",
56 $nbEntries
57 )
58 );
59
60 if (!$io->confirm('Are you sure you want to proceed?')) {
61 return 0;
62 }
63
64 $progressBar = $io->createProgressBar($nbEntries);
65
66 $contentProxy = $this->getContainer()->get('wallabag_core.content_proxy');
67 $em = $this->getContainer()->get('doctrine')->getManager();
68 $dispatcher = $this->getContainer()->get('event_dispatcher');
69
70 $progressBar->start();
71 foreach ($entryIds as $entryId) {
72 $entry = $entryRepository->find($entryId);
73
74 $contentProxy->updateEntry($entry, $entry->getUrl());
75 $em->persist($entry);
76 $em->flush();
77
78 $dispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
79 $progressBar->advance();
80
81 $em->detach($entry);
82 }
83 $progressBar->finish();
84
85 $io->newLine(2);
86 $io->success('Done.');
87
88 return 0;
89 }
90}
diff --git a/src/Wallabag/CoreBundle/Command/ShowUserCommand.php b/src/Wallabag/CoreBundle/Command/ShowUserCommand.php
index 090309d9..2dca32c4 100644
--- a/src/Wallabag/CoreBundle/Command/ShowUserCommand.php
+++ b/src/Wallabag/CoreBundle/Command/ShowUserCommand.php
@@ -52,11 +52,11 @@ class ShowUserCommand extends ContainerAwareCommand
52 private function showUser(User $user) 52 private function showUser(User $user)
53 { 53 {
54 $this->io->listing([ 54 $this->io->listing([
55 sprintf('Username : %s', $user->getUsername()), 55 sprintf('Username: %s', $user->getUsername()),
56 sprintf('Email : %s', $user->getEmail()), 56 sprintf('Email: %s', $user->getEmail()),
57 sprintf('Display name : %s', $user->getName()), 57 sprintf('Display name: %s', $user->getName()),
58 sprintf('Creation date : %s', $user->getCreatedAt()->format('Y-m-d H:i:s')), 58 sprintf('Creation date: %s', $user->getCreatedAt()->format('Y-m-d H:i:s')),
59 sprintf('Last login : %s', $user->getLastLogin() !== null ? $user->getLastLogin()->format('Y-m-d H:i:s') : 'never'), 59 sprintf('Last login: %s', $user->getLastLogin() !== null ? $user->getLastLogin()->format('Y-m-d H:i:s') : 'never'),
60 sprintf('2FA activated: %s', $user->isTwoFactorAuthentication() ? 'yes' : 'no'), 60 sprintf('2FA activated: %s', $user->isTwoFactorAuthentication() ? 'yes' : 'no'),
61 ]); 61 ]);
62 } 62 }
diff --git a/src/Wallabag/CoreBundle/Command/TagAllCommand.php b/src/Wallabag/CoreBundle/Command/TagAllCommand.php
index 9843674e..4afac2d4 100644
--- a/src/Wallabag/CoreBundle/Command/TagAllCommand.php
+++ b/src/Wallabag/CoreBundle/Command/TagAllCommand.php
@@ -7,6 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
7use Symfony\Component\Console\Input\InputArgument; 7use Symfony\Component\Console\Input\InputArgument;
8use Symfony\Component\Console\Input\InputInterface; 8use Symfony\Component\Console\Input\InputInterface;
9use Symfony\Component\Console\Output\OutputInterface; 9use Symfony\Component\Console\Output\OutputInterface;
10use Symfony\Component\Console\Style\SymfonyStyle;
10 11
11class TagAllCommand extends ContainerAwareCommand 12class TagAllCommand extends ContainerAwareCommand
12{ 13{
@@ -25,21 +26,22 @@ class TagAllCommand extends ContainerAwareCommand
25 26
26 protected function execute(InputInterface $input, OutputInterface $output) 27 protected function execute(InputInterface $input, OutputInterface $output)
27 { 28 {
29 $io = new SymfonyStyle($input, $output);
30
28 try { 31 try {
29 $user = $this->getUser($input->getArgument('username')); 32 $user = $this->getUser($input->getArgument('username'));
30 } catch (NoResultException $e) { 33 } catch (NoResultException $e) {
31 $output->writeln(sprintf('<error>User "%s" not found.</error>', $input->getArgument('username'))); 34 $io->error(sprintf('User "%s" not found.', $input->getArgument('username')));
32 35
33 return 1; 36 return 1;
34 } 37 }
35 $tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger'); 38 $tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger');
36 39
37 $output->write(sprintf('Tagging entries for user « <comment>%s</comment> »... ', $user->getUserName())); 40 $io->text(sprintf('Tagging entries for user <info>%s</info>...', $user->getUserName()));
38 41
39 $entries = $tagger->tagAllForUser($user); 42 $entries = $tagger->tagAllForUser($user);
40 43
41 $output->writeln('<info>Done.</info>'); 44 $io->text('Persist entries... ');
42 $output->write(sprintf('Persist entries ... ', $user->getUserName()));
43 45
44 $em = $this->getDoctrine()->getManager(); 46 $em = $this->getDoctrine()->getManager();
45 foreach ($entries as $entry) { 47 foreach ($entries as $entry) {
@@ -47,7 +49,9 @@ class TagAllCommand extends ContainerAwareCommand
47 } 49 }
48 $em->flush(); 50 $em->flush();
49 51
50 $output->writeln('<info>Done.</info>'); 52 $io->success('Done.');
53
54 return 0;
51 } 55 }
52 56
53 /** 57 /**
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 845ebef6..3dcfbebe 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -573,6 +573,7 @@ class EntryController extends Controller
573 'entries' => $entries, 573 'entries' => $entries,
574 'currentPage' => $page, 574 'currentPage' => $page,
575 'searchTerm' => $searchTerm, 575 'searchTerm' => $searchTerm,
576 'isFiltered' => $form->isSubmitted(),
576 ] 577 ]
577 ); 578 );
578 } 579 }
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php
index f2ca58c6..be2dff98 100644
--- a/src/Wallabag/CoreBundle/Controller/TagController.php
+++ b/src/Wallabag/CoreBundle/Controller/TagController.php
@@ -84,28 +84,11 @@ class TagController extends Controller
84 */ 84 */
85 public function showTagAction() 85 public function showTagAction()
86 { 86 {
87 $repository = $this->get('wallabag_core.entry_repository');
88 $tags = $this->get('wallabag_core.tag_repository') 87 $tags = $this->get('wallabag_core.tag_repository')
89 ->findAllTags($this->getUser()->getId()); 88 ->findAllFlatTagsWithNbEntries($this->getUser()->getId());
90
91 $flatTags = [];
92
93 foreach ($tags as $tag) {
94 $nbEntries = $repository->countAllEntriesByUserIdAndTagId(
95 $this->getUser()->getId(),
96 $tag->getId()
97 );
98
99 $flatTags[] = [
100 'id' => $tag->getId(),
101 'label' => $tag->getLabel(),
102 'slug' => $tag->getSlug(),
103 'nbEntries' => $nbEntries,
104 ];
105 }
106 89
107 return $this->render('WallabagCoreBundle:Tag:tags.html.twig', [ 90 return $this->render('WallabagCoreBundle:Tag:tags.html.twig', [
108 'tags' => $flatTags, 91 'tags' => $tags,
109 ]); 92 ]);
110 } 93 }
111 94
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
index 10689c62..da19fe31 100644
--- a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
+++ b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
@@ -8,6 +8,7 @@ use Graby\SiteConfig\ConfigBuilder;
8use Psr\Log\LoggerInterface; 8use Psr\Log\LoggerInterface;
9use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; 9use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
10use Wallabag\CoreBundle\Repository\SiteCredentialRepository; 10use Wallabag\CoreBundle\Repository\SiteCredentialRepository;
11use Wallabag\UserBundle\Entity\User;
11 12
12class GrabySiteConfigBuilder implements SiteConfigBuilder 13class GrabySiteConfigBuilder implements SiteConfigBuilder
13{ 14{
@@ -27,7 +28,7 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
27 private $logger; 28 private $logger;
28 29
29 /** 30 /**
30 * @var Wallabag\UserBundle\Entity\User|null 31 * @var User|null
31 */ 32 */
32 private $currentUser; 33 private $currentUser;
33 34
diff --git a/src/Wallabag/CoreBundle/Helper/EntriesExport.php b/src/Wallabag/CoreBundle/Helper/EntriesExport.php
index 64d82193..de259e7f 100644
--- a/src/Wallabag/CoreBundle/Helper/EntriesExport.php
+++ b/src/Wallabag/CoreBundle/Helper/EntriesExport.php
@@ -2,12 +2,12 @@
2 2
3namespace Wallabag\CoreBundle\Helper; 3namespace Wallabag\CoreBundle\Helper;
4 4
5use JMS\Serializer;
6use JMS\Serializer\SerializationContext; 5use JMS\Serializer\SerializationContext;
7use JMS\Serializer\SerializerBuilder; 6use JMS\Serializer\SerializerBuilder;
8use PHPePub\Core\EPub; 7use PHPePub\Core\EPub;
9use PHPePub\Core\Structure\OPF\DublinCore; 8use PHPePub\Core\Structure\OPF\DublinCore;
10use Symfony\Component\HttpFoundation\Response; 9use Symfony\Component\HttpFoundation\Response;
10use Wallabag\CoreBundle\Entity\Entry;
11 11
12/** 12/**
13 * This class doesn't have unit test BUT it's fully covered by a functional test with ExportControllerTest. 13 * This class doesn't have unit test BUT it's fully covered by a functional test with ExportControllerTest.
@@ -427,7 +427,7 @@ class EntriesExport
427 * 427 *
428 * @param string $format 428 * @param string $format
429 * 429 *
430 * @return Serializer 430 * @return string
431 */ 431 */
432 private function prepareSerializingContent($format) 432 private function prepareSerializingContent($format)
433 { 433 {
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index c27ee90c..eb5e3205 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -3,9 +3,10 @@
3namespace Wallabag\CoreBundle\Repository; 3namespace Wallabag\CoreBundle\Repository;
4 4
5use Doctrine\ORM\EntityRepository; 5use Doctrine\ORM\EntityRepository;
6use Doctrine\ORM\Query; 6use Doctrine\ORM\QueryBuilder;
7use Pagerfanta\Adapter\DoctrineORMAdapter; 7use Pagerfanta\Adapter\DoctrineORMAdapter;
8use Pagerfanta\Pagerfanta; 8use Pagerfanta\Pagerfanta;
9use Wallabag\CoreBundle\Entity\Entry;
9use Wallabag\CoreBundle\Entity\Tag; 10use Wallabag\CoreBundle\Entity\Tag;
10 11
11class EntryRepository extends EntityRepository 12class EntryRepository extends EntityRepository
@@ -74,7 +75,7 @@ class EntryRepository extends EntityRepository
74 * 75 *
75 * @param int $userId 76 * @param int $userId
76 * @param string $term 77 * @param string $term
77 * @param strint $currentRoute 78 * @param string $currentRoute
78 * 79 *
79 * @return QueryBuilder 80 * @return QueryBuilder
80 */ 81 */
@@ -126,7 +127,7 @@ class EntryRepository extends EntityRepository
126 * @param int $since 127 * @param int $since
127 * @param string $tags 128 * @param string $tags
128 * 129 *
129 * @return array 130 * @return Pagerfanta
130 */ 131 */
131 public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'ASC', $since = 0, $tags = '') 132 public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'ASC', $since = 0, $tags = '')
132 { 133 {
@@ -172,7 +173,7 @@ class EntryRepository extends EntityRepository
172 * 173 *
173 * @param int $userId 174 * @param int $userId
174 * 175 *
175 * @return Entry 176 * @return array
176 */ 177 */
177 public function findOneWithTags($userId) 178 public function findOneWithTags($userId)
178 { 179 {
@@ -329,26 +330,6 @@ class EntryRepository extends EntityRepository
329 } 330 }
330 331
331 /** 332 /**
332 * Count all entries for a tag and a user.
333 *
334 * @param int $userId
335 * @param int $tagId
336 *
337 * @return int
338 */
339 public function countAllEntriesByUserIdAndTagId($userId, $tagId)
340 {
341 $qb = $this->createQueryBuilder('e')
342 ->select('count(e.id)')
343 ->leftJoin('e.tags', 't')
344 ->where('e.user=:userId')->setParameter('userId', $userId)
345 ->andWhere('t.id=:tagId')->setParameter('tagId', $tagId)
346 ;
347
348 return (int) $qb->getQuery()->getSingleScalarResult();
349 }
350
351 /**
352 * Remove all entries for a user id. 333 * Remove all entries for a user id.
353 * Used when a user want to reset all informations. 334 * Used when a user want to reset all informations.
354 * 335 *
@@ -374,7 +355,7 @@ class EntryRepository extends EntityRepository
374 * Get id and url from all entries 355 * Get id and url from all entries
375 * Used for the clean-duplicates command. 356 * Used for the clean-duplicates command.
376 */ 357 */
377 public function getAllEntriesIdAndUrl($userId) 358 public function findAllEntriesIdAndUrlByUserId($userId)
378 { 359 {
379 $qb = $this->createQueryBuilder('e') 360 $qb = $this->createQueryBuilder('e')
380 ->select('e.id, e.url') 361 ->select('e.id, e.url')
@@ -384,6 +365,23 @@ class EntryRepository extends EntityRepository
384 } 365 }
385 366
386 /** 367 /**
368 * @param int $userId
369 *
370 * @return array
371 */
372 public function findAllEntriesIdByUserId($userId = null)
373 {
374 $qb = $this->createQueryBuilder('e')
375 ->select('e.id');
376
377 if (null !== $userId) {
378 $qb->where('e.user = :userid')->setParameter(':userid', $userId);
379 }
380
381 return $qb->getQuery()->getArrayResult();
382 }
383
384 /**
387 * Find all entries by url and owner. 385 * Find all entries by url and owner.
388 * 386 *
389 * @param $url 387 * @param $url
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php
index 6c63a6a2..5c45211f 100644
--- a/src/Wallabag/CoreBundle/Repository/TagRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php
@@ -3,6 +3,7 @@
3namespace Wallabag\CoreBundle\Repository; 3namespace Wallabag\CoreBundle\Repository;
4 4
5use Doctrine\ORM\EntityRepository; 5use Doctrine\ORM\EntityRepository;
6use Wallabag\CoreBundle\Entity\Tag;
6 7
7class TagRepository extends EntityRepository 8class TagRepository extends EntityRepository
8{ 9{
@@ -62,6 +63,27 @@ class TagRepository extends EntityRepository
62 } 63 }
63 64
64 /** 65 /**
66 * Find all tags (flat) per user with nb entries.
67 *
68 * @param int $userId
69 *
70 * @return array
71 */
72 public function findAllFlatTagsWithNbEntries($userId)
73 {
74 return $this->createQueryBuilder('t')
75 ->select('t.id, t.label, t.slug, count(e.id) as nbEntries')
76 ->distinct(true)
77 ->leftJoin('t.entries', 'e')
78 ->where('e.user = :userId')
79 ->groupBy('t.id')
80 ->orderBy('t.slug')
81 ->setParameter('userId', $userId)
82 ->getQuery()
83 ->getArrayResult();
84 }
85
86 /**
65 * Used only in test case to get a tag for our entry. 87 * Used only in test case to get a tag for our entry.
66 * 88 *
67 * @return Tag 89 * @return Tag
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index 5229ac73..5e5bbde2 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -169,6 +169,7 @@ entry:
169 # filtered_tags: 'Filtered by tags:' 169 # filtered_tags: 'Filtered by tags:'
170 # filtered_search: 'Filtered by search:' 170 # filtered_search: 'Filtered by search:'
171 # untagged: 'Untagged entries' 171 # untagged: 'Untagged entries'
172 # all: 'All entries'
172 list: 173 list:
173 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 174 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
174 reading_time: 'estimeret læsetid' 175 reading_time: 'estimeret læsetid'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index 996f173a..48f8a535 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: 'Gefiltert nach Tags:' 169 filtered_tags: 'Gefiltert nach Tags:'
170 filtered_search: 'Gefiltert nach Suche:' 170 filtered_search: 'Gefiltert nach Suche:'
171 untagged: 'Nicht getaggte Einträge' 171 untagged: 'Nicht getaggte Einträge'
172 all: 'Alle Einträge'
172 list: 173 list:
173 number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.' 174 number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.'
174 reading_time: 'geschätzte Lesezeit' 175 reading_time: 'geschätzte Lesezeit'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index aa1cd1a9..f41a7c85 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: 'Filtered by tags:' 169 filtered_tags: 'Filtered by tags:'
170 filtered_search: 'Filtered by search:' 170 filtered_search: 'Filtered by search:'
171 untagged: 'Untagged entries' 171 untagged: 'Untagged entries'
172 all: 'All entries'
172 list: 173 list:
173 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 174 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
174 reading_time: 'estimated reading time' 175 reading_time: 'estimated reading time'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index 96998f53..ea4d84ba 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: 'Filtrado por etiquetas:' 169 filtered_tags: 'Filtrado por etiquetas:'
170 filtered_search: 'Filtrado por búsqueda:' 170 filtered_search: 'Filtrado por búsqueda:'
171 untagged: 'Artículos sin etiquetas' 171 untagged: 'Artículos sin etiquetas'
172 all: "Todos los artículos"
172 list: 173 list:
173 number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.' 174 number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.'
174 reading_time: 'tiempo estimado de lectura' 175 reading_time: 'tiempo estimado de lectura'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index 57e6c029..11047e83 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -169,6 +169,7 @@ entry:
169 # filtered_tags: 'Filtered by tags:' 169 # filtered_tags: 'Filtered by tags:'
170 # filtered_search: 'Filtered by search:' 170 # filtered_search: 'Filtered by search:'
171 # untagged: 'Untagged entries' 171 # untagged: 'Untagged entries'
172 # all: 'All entries'
172 list: 173 list:
173 number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.' 174 number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.'
174 reading_time: 'زمان تخمینی برای خواندن' 175 reading_time: 'زمان تخمینی برای خواندن'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 6eac4c36..246add86 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: "Articles filtrés par tags :" 169 filtered_tags: "Articles filtrés par tags :"
170 filtered_search: "Articles filtrés par recherche :" 170 filtered_search: "Articles filtrés par recherche :"
171 untagged: "Article sans tag" 171 untagged: "Article sans tag"
172 all: "Tous les articles"
172 list: 173 list:
173 number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles." 174 number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles."
174 reading_time: "durée de lecture" 175 reading_time: "durée de lecture"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index fa7ae0b2..0de8bed7 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: 'Filtrati per etichetta:' 169 filtered_tags: 'Filtrati per etichetta:'
170 filtered_search: 'Filtrati per ricerca:' 170 filtered_search: 'Filtrati per ricerca:'
171 untagged: 'Articoli non etichettati' 171 untagged: 'Articoli non etichettati'
172 all: 'Tutti gli articoli'
172 list: 173 list:
173 number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti." 174 number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti."
174 reading_time: 'tempo di lettura stimato' 175 reading_time: 'tempo di lettura stimato'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index be57e903..c2b49247 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -2,7 +2,7 @@ security:
2 login: 2 login:
3 page_title: 'Benvenguda sus wallabag !' 3 page_title: 'Benvenguda sus wallabag !'
4 keep_logged_in: 'Demorar connectat' 4 keep_logged_in: 'Demorar connectat'
5 forgot_password: 'Senhal doblidat ?' 5 forgot_password: 'Senhal oblidat ?'
6 submit: 'Se connectar' 6 submit: 'Se connectar'
7 register: 'Crear un compte' 7 register: 'Crear un compte'
8 username: "Nom d'utilizaire" 8 username: "Nom d'utilizaire"
@@ -12,7 +12,7 @@ security:
12 description: "Picatz vòstra adreça de corrièl çai-jos, vos mandarem las instruccions per reïnicializar vòstre senhal." 12 description: "Picatz vòstra adreça de corrièl çai-jos, vos mandarem las instruccions per reïnicializar vòstre senhal."
13 register: 13 register:
14 page_title: 'Se crear un compte' 14 page_title: 'Se crear un compte'
15 go_to_account: 'Anar sus vòstre compte' 15 go_to_account: 'Anar a vòstre compte'
16 16
17menu: 17menu:
18 left: 18 left:
@@ -22,7 +22,7 @@ menu:
22 all_articles: 'Totes los articles' 22 all_articles: 'Totes los articles'
23 config: 'Configuracion' 23 config: 'Configuracion'
24 tags: 'Etiquetas' 24 tags: 'Etiquetas'
25 internal_settings: 'Configuracion interna' 25 internal_settings: 'Configuracion intèrna'
26 import: 'Importar' 26 import: 'Importar'
27 howto: 'Ajuda' 27 howto: 'Ajuda'
28 developer: 'Gestion dels clients API' 28 developer: 'Gestion dels clients API'
@@ -32,7 +32,7 @@ menu:
32 save_link: 'Enregistrar un novèl article' 32 save_link: 'Enregistrar un novèl article'
33 back_to_unread: 'Tornar als articles pas legits' 33 back_to_unread: 'Tornar als articles pas legits'
34 users_management: 'Gestion dels utilizaires' 34 users_management: 'Gestion dels utilizaires'
35 # site_credentials: 'Site credentials' 35 site_credentials: 'Identificants del site'
36 top: 36 top:
37 add_new_entry: 'Enregistrar un novèl article' 37 add_new_entry: 'Enregistrar un novèl article'
38 search: 'Cercar' 38 search: 'Cercar'
@@ -77,7 +77,7 @@ config:
77 redirect_current_page: 'A la pagina actuala' 77 redirect_current_page: 'A la pagina actuala'
78 pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas 78 pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas
79 android_configuration: Configuratz vòstra aplicacion Android 79 android_configuration: Configuratz vòstra aplicacion Android
80 # android_instruction: "Touch here to prefill your Android application" 80 android_instruction: "Tocatz aquí per garnir las informacions de l'aplicacion Android"
81 help_theme: "wallabag es personalizable. Podètz causir vòstre tèma preferit aquí." 81 help_theme: "wallabag es personalizable. Podètz causir vòstre tèma preferit aquí."
82 help_items_per_page: "Podètz cambiar lo nombre d'articles afichats per pagina." 82 help_items_per_page: "Podètz cambiar lo nombre d'articles afichats per pagina."
83 help_reading_speed: "wallabag calcula lo temps de lectura per cada article. Podètz lo definir aquí, gràcias a aquesta lista, se sètz un legeire rapid o lent. wallabag tornarà calcular lo temps de lectura per cada article." 83 help_reading_speed: "wallabag calcula lo temps de lectura per cada article. Podètz lo definir aquí, gràcias a aquesta lista, se sètz un legeire rapid o lent. wallabag tornarà calcular lo temps de lectura per cada article."
@@ -94,14 +94,14 @@ config:
94 unread: 'Pas legits' 94 unread: 'Pas legits'
95 starred: 'Favorits' 95 starred: 'Favorits'
96 archive: 'Legits' 96 archive: 'Legits'
97 # all: 'All' 97 all: 'Totes'
98 rss_limit: "Nombre d'articles dins un flux RSS" 98 rss_limit: "Nombre d'articles dins un flux RSS"
99 form_user: 99 form_user:
100 two_factor_description: "Activar l'autentificacion doble-factor vòl dire que recebretz un còdi per corrièl per cada novèla connexion pas aprovada." 100 two_factor_description: "Activar l'autentificacion en dos temps vòl dire que recebretz un còdi per corrièl per cada novèla connexion pas aprovada."
101 name_label: 'Nom' 101 name_label: 'Nom'
102 email_label: 'Adreça de corrièl' 102 email_label: 'Adreça de corrièl'
103 twoFactorAuthentication_label: 'Dobla autentificacion' 103 twoFactorAuthentication_label: 'Dobla autentificacion'
104 help_twoFactorAuthentication: "S'avètz activat 2FA, cada còp que volètz vos connectar a wallabag, recebretz un còdi per corrièl." 104 help_twoFactorAuthentication: "S'avètz activat l'autentificacion en dos temps, cada còp que volètz vos connectar a wallabag, recebretz un còdi per corrièl."
105 delete: 105 delete:
106 title: Suprimir mon compte (Mèfi zòna perilhosa) 106 title: Suprimir mon compte (Mèfi zòna perilhosa)
107 description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat. 107 description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat.
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: 'Articles filtrats per etiquetas :' 169 filtered_tags: 'Articles filtrats per etiquetas :'
170 filtered_search: 'Articles filtrats per recèrca :' 170 filtered_search: 'Articles filtrats per recèrca :'
171 untagged: 'Articles sens etiqueta' 171 untagged: 'Articles sens etiqueta'
172 all: 'Totes los articles'
172 list: 173 list:
173 number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles." 174 number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles."
174 reading_time: 'durada de lectura' 175 reading_time: 'durada de lectura'
@@ -190,8 +191,8 @@ entry:
190 unread_label: 'Pas legits' 191 unread_label: 'Pas legits'
191 preview_picture_label: 'A un imatge' 192 preview_picture_label: 'A un imatge'
192 preview_picture_help: 'Imatge' 193 preview_picture_help: 'Imatge'
193 # is_public_label: 'Has a public link' 194 is_public_label: 'Ten un ligam public'
194 # is_public_help: 'Public link' 195 is_public_help: 'Ligam public'
195 language_label: 'Lenga' 196 language_label: 'Lenga'
196 http_status_label: 'Estatut HTTP' 197 http_status_label: 'Estatut HTTP'
197 reading_time: 198 reading_time:
@@ -212,7 +213,7 @@ entry:
212 back_to_homepage: 'Tornar' 213 back_to_homepage: 'Tornar'
213 set_as_read: 'Marcar coma legit' 214 set_as_read: 'Marcar coma legit'
214 set_as_unread: 'Marcar coma pas legit' 215 set_as_unread: 'Marcar coma pas legit'
215 set_as_starred: 'Metre en favori' 216 set_as_starred: 'Metre en favorit'
216 view_original_article: 'Article original' 217 view_original_article: 'Article original'
217 re_fetch_content: 'Tornar cargar lo contengut' 218 re_fetch_content: 'Tornar cargar lo contengut'
218 delete: 'Suprimir' 219 delete: 'Suprimir'
@@ -247,8 +248,8 @@ entry:
247 public: 248 public:
248 shared_by_wallabag: "Aqueste article es estat partejat per <a href='%wallabag_instance%'>wallabag</a>" 249 shared_by_wallabag: "Aqueste article es estat partejat per <a href='%wallabag_instance%'>wallabag</a>"
249 confirm: 250 confirm:
250 # delete: "Are you sure you want to remove that article?" 251 delete: "Sètz segur de voler suprimir aqueste article ?"
251 # delete_tag: "Are you sure you want to remove that tag from that article?" 252 delete_tag: "Sètz segur de voler levar aquesta etiqueta de l'article ?"
252 253
253about: 254about:
254 page_title: 'A prepaus' 255 page_title: 'A prepaus'
@@ -338,7 +339,7 @@ quickstart:
338 more: 'Mai…' 339 more: 'Mai…'
339 intro: 340 intro:
340 title: 'Benvenguda sus wallabag !' 341 title: 'Benvenguda sus wallabag !'
341 paragraph_1: "Anem vos guidar per far lo torn de la proprietat e vos presentar unas fonccionalitats que vos poirián interessar per vos apropriar aquesta aisina." 342 paragraph_1: "Anem vos guidar per far lo torn de la proprietat e vos presentar unas foncionalitats que vos poirián interessar per vos apropriar aquesta aisina."
342 paragraph_2: 'Seguètz-nos !' 343 paragraph_2: 'Seguètz-nos !'
343 configure: 344 configure:
344 title: "Configuratz l'aplicacion" 345 title: "Configuratz l'aplicacion"
@@ -358,7 +359,7 @@ quickstart:
358 title: 'Primièrs passes' 359 title: 'Primièrs passes'
359 description: "Ara wallabag es ben configurat, es lo moment d'archivar lo web. Podètz clicar sul signe + a man drecha amont per ajustar un ligam." 360 description: "Ara wallabag es ben configurat, es lo moment d'archivar lo web. Podètz clicar sul signe + a man drecha amont per ajustar un ligam."
360 new_article: 'Ajustatz vòstre primièr article' 361 new_article: 'Ajustatz vòstre primièr article'
361 unread_articles: 'E racaptatz-lo !' 362 unread_articles: 'E recaptatz-lo !'
362 migrate: 363 migrate:
363 title: 'Migrar dempuèi un servici existent' 364 title: 'Migrar dempuèi un servici existent'
364 description: "Sètz un ancian utilizaire d'un servici existent ? Vos ajudarem a trapar vòstras donadas sus wallabag." 365 description: "Sètz un ancian utilizaire d'un servici existent ? Vos ajudarem a trapar vòstras donadas sus wallabag."
@@ -374,7 +375,7 @@ quickstart:
374 use_docker: 'Utilizar Docker per installar wallabag' 375 use_docker: 'Utilizar Docker per installar wallabag'
375 docs: 376 docs:
376 title: 'Documentacion complèta' 377 title: 'Documentacion complèta'
377 description: "I a un fum de fonccionalitats dins wallabag. Esitetz pas a legir lo manual per las conéisser e aprendre a las utilizar." 378 description: "I a un fum de foncionalitats dins wallabag. Esitetz pas a legir lo manual per las conéisser e aprendre a las utilizar."
378 annotate: 'Anotar vòstre article' 379 annotate: 'Anotar vòstre article'
379 export: 'Convertissètz vòstres articles en ePub o en PDF' 380 export: 'Convertissètz vòstres articles en ePub o en PDF'
380 search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa" 381 search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa"
@@ -417,11 +418,11 @@ import:
417 connect_to_pocket: 'Se connectar a Pocket e importar las donadas' 418 connect_to_pocket: 'Se connectar a Pocket e importar las donadas'
418 wallabag_v1: 419 wallabag_v1:
419 page_title: 'Importar > Wallabag v1' 420 page_title: 'Importar > Wallabag v1'
420 description: 'Aquesta aisina importarà totas vòstras donadas de wallabag v1. Sus vòstre pagina de configuracion de wallabag v1, clicatz sus \"Export JSON\" dins la seccion \"Exportar vòstras donadas de wallabag\". Traparatz un fichièr \"wallabag-export-1-xxxx-xx-xx.json\".' 421 description: 'Aquesta aisina importarà totas vòstras donadas de wallabag v1. Sus vòstre pagina de configuracion de wallabag v1, clicatz sus \"Export JSON\" dins la seccion \"Exportar vòstras donadas de wallabag\". Traparetz un fichièr \"wallabag-export-1-xxxx-xx-xx.json\".'
421 how_to: "Causissètz lo fichièr de vòstra exportacion wallabag v1 e clicatz sul boton çai-jos per l'importar." 422 how_to: "Causissètz lo fichièr de vòstra exportacion wallabag v1 e clicatz sul boton çai-jos per l'importar."
422 wallabag_v2: 423 wallabag_v2:
423 page_title: 'Importar > Wallabag v2' 424 page_title: 'Importar > Wallabag v2'
424 description: "Aquesta aisina importarà totas vòstras donadas d'una instància mai de wallabag v2. Anatz dins totes vòstres articles, puèi, sus la barra laterala, clicatz sus \"JSON\". Traparatz un fichièr \"All articles.json\"." 425 description: "Aquesta aisina importarà totas vòstras donadas d'una instància mai de wallabag v2. Anatz dins totes vòstres articles, puèi, sus la barra laterala, clicatz sus \"JSON\". Traparetz un fichièr \"All articles.json\"."
425 readability: 426 readability:
426 page_title: 'Importar > Readability' 427 page_title: 'Importar > Readability'
427 description: "Aquesta aisina importarà totas vòstres articles de Readability. Sus la pagina de l'aisina (https://www.readability.com/tools/), clicatz sus \"Export your data\" dins la seccion \"Data Export\". Recebretz un corrièl per telecargar un json (qu'acaba pas amb un .json de fach)." 428 description: "Aquesta aisina importarà totas vòstres articles de Readability. Sus la pagina de l'aisina (https://www.readability.com/tools/), clicatz sus \"Export your data\" dins la seccion \"Data Export\". Recebretz un corrièl per telecargar un json (qu'acaba pas amb un .json de fach)."
@@ -431,7 +432,7 @@ import:
431 download_images_warning: "Avètz activat lo telecargament de los imatges de vòstres articles. Combinat amb l'importacion classica, aquò pòt tardar un long moment (o benlèu fracassar). <strong>Recomandem fòrtament</strong> l'activacion de l'importacion asincròna per evitar las errors." 432 download_images_warning: "Avètz activat lo telecargament de los imatges de vòstres articles. Combinat amb l'importacion classica, aquò pòt tardar un long moment (o benlèu fracassar). <strong>Recomandem fòrtament</strong> l'activacion de l'importacion asincròna per evitar las errors."
432 firefox: 433 firefox:
433 page_title: 'Importar > Firefox' 434 page_title: 'Importar > Firefox'
434 description: "Aquesta aisina importarà totas vòstres favorits de Firefox. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." 435 description: "Aquesta aisina importarà totas vòstres favorits de Firefox. Anatz simplament dins vòstres marcapaginas (Ctrl+Maj+O), puèi dins \"Impòrt e salvagarda\", causissètz \"Salvagardar...\". Auretz un fichièr .json."
435 how_to: "Mercés de causir lo fichièr de salvagarda e de clicar sul boton dejós per l'importar. Notatz que lo tractament pòt durar un moment ja que totes los articles an d'èsser recuperats." 436 how_to: "Mercés de causir lo fichièr de salvagarda e de clicar sul boton dejós per l'importar. Notatz que lo tractament pòt durar un moment ja que totes los articles an d'èsser recuperats."
436 chrome: 437 chrome:
437 page_title: 'Importar > Chrome' 438 page_title: 'Importar > Chrome'
@@ -459,12 +460,12 @@ developer:
459 existing_clients: 460 existing_clients:
460 title: 'Los clients existents' 461 title: 'Los clients existents'
461 field_id: 'ID Client' 462 field_id: 'ID Client'
462 field_secret: 'Clé secreta' 463 field_secret: 'Clau secrèta'
463 field_uris: 'URLs de redireccion' 464 field_uris: 'URLs de redireccion'
464 field_grant_types: 'Tipe de privilègi acordat' 465 field_grant_types: 'Tipe de privilègi acordat'
465 no_client: 'Pas cap de client pel moment.' 466 no_client: 'Pas cap de client pel moment.'
466 remove: 467 remove:
467 warn_message_1: 'Avètz la possibilitat de supriimr un client. Aquesta accion es IRREVERSIBLA !' 468 warn_message_1: 'Avètz la possibilitat de suprimir un client. Aquesta accion es IRREVERSIBLA !'
468 warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag." 469 warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag."
469 action: 'Suprimir aqueste client' 470 action: 'Suprimir aqueste client'
470 client: 471 client:
@@ -525,20 +526,20 @@ user:
525 placeholder: "Filtrar per nom d'utilizaire o corrièl" 526 placeholder: "Filtrar per nom d'utilizaire o corrièl"
526 527
527site_credential: 528site_credential:
528 # page_title: Site credentials management 529 page_title: Gestion dels identificants
529 # new_site_credential: Create a credential 530 new_site_credential: Crear un identificant
530 # edit_site_credential: Edit an existing credential 531 edit_site_credential: Modificar un identificant
531 # description: "Here you can manage all credentials for sites which required them (create, edit and delete), like a paywall, an authentication, etc." 532 description: "Aquí podètz gerir vòstres identificants pels sites que los demandan (ne crear, ne modifiar, ne suprimir) coma los sites a peatge, etc."
532 list: 533 list:
533 actions: 'Accions' 534 actions: 'Accions'
534 edit_action: 'Modificar' 535 edit_action: 'Modificar'
535 yes: 'Òc' 536 yes: 'Òc'
536 no: 'Non' 537 no: 'Non'
537 # create_new_one: Create a new credential 538 create_new_one: Crear un novèl identificant
538 form: 539 form:
539 # username_label: 'Username' 540 username_label: "Nom d'utilizaire"
540 # host_label: 'Host' 541 host_label: 'Òste'
541 # password_label: 'Password' 542 password_label: 'Senhal'
542 save: 'Enregistrar' 543 save: 'Enregistrar'
543 delete: 'Suprimir' 544 delete: 'Suprimir'
544 delete_confirm: 'Sètz segur ?' 545 delete_confirm: 'Sètz segur ?'
@@ -552,7 +553,7 @@ flashes:
552 notice: 553 notice:
553 config_saved: 'Los paramètres son ben estats meses a jorn.' 554 config_saved: 'Los paramètres son ben estats meses a jorn.'
554 password_updated: 'Vòstre senhal es ben estat mes a jorn' 555 password_updated: 'Vòstre senhal es ben estat mes a jorn'
555 password_not_updated_demo: "En demostration, podètz pas cambiar lo senhal d'aqueste utilizaire." 556 password_not_updated_demo: "En demostracion, podètz pas cambiar lo senhal d'aqueste utilizaire."
556 user_updated: 'Vòstres informacions personnelas son ben estadas mesas a jorn' 557 user_updated: 'Vòstres informacions personnelas son ben estadas mesas a jorn'
557 rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn' 558 rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn'
558 tagging_rules_updated: 'Règlas misa a jorn' 559 tagging_rules_updated: 'Règlas misa a jorn'
@@ -564,7 +565,7 @@ flashes:
564 archived_reset: Articles archivat suprimits 565 archived_reset: Articles archivat suprimits
565 entry: 566 entry:
566 notice: 567 notice:
567 entry_already_saved: 'Article ja salvargardat lo %date%' 568 entry_already_saved: 'Article ja salvagardat lo %date%'
568 entry_saved: 'Article enregistrat' 569 entry_saved: 'Article enregistrat'
569 entry_saved_failed: 'Article salvat mai fracàs de la recuperacion del contengut' 570 entry_saved_failed: 'Article salvat mai fracàs de la recuperacion del contengut'
570 entry_updated: 'Article mes a jorn' 571 entry_updated: 'Article mes a jorn'
@@ -581,9 +582,9 @@ flashes:
581 import: 582 import:
582 notice: 583 notice:
583 failed: "L'importacion a fracassat, mercés de tornar ensajar." 584 failed: "L'importacion a fracassat, mercés de tornar ensajar."
584 failed_on_file: "Errorr pendent du tractament de l'import. Mercés de verificar vòstre fichièr." 585 failed_on_file: "Error en tractar l'impòrt. Mercés de verificar vòstre fichièr."
585 summary: "Rapòrt d'import: %imported% importats, %skipped% ja presents." 586 summary: "Rapòrt d'impòrt: %imported% importats, %skipped% ja presents."
586 summary_with_queue: "Rapòrt d'import : %queued% en espèra de tractament." 587 summary_with_queue: "Rapòrt d'impòrt : %queued% en espèra de tractament."
587 error: 588 error:
588 redis_enabled_not_installed: "Redis es capable d'importar de manièra asincròna mai sembla que <u>podèm pas nos conectar amb el</u>. Mercés de verificar la configuracion de Redis." 589 redis_enabled_not_installed: "Redis es capable d'importar de manièra asincròna mai sembla que <u>podèm pas nos conectar amb el</u>. Mercés de verificar la configuracion de Redis."
589 rabbit_enabled_not_installed: "RabbitMQ es capable d'importar de manièra asincròna mai sembla que <u>podèm pas nos conectar amb el</u>. Mercés de verificar la configuracion de RabbitMQ." 590 rabbit_enabled_not_installed: "RabbitMQ es capable d'importar de manièra asincròna mai sembla que <u>podèm pas nos conectar amb el</u>. Mercés de verificar la configuracion de RabbitMQ."
@@ -598,6 +599,6 @@ flashes:
598 deleted: 'Utilizaire "%username%" suprimit' 599 deleted: 'Utilizaire "%username%" suprimit'
599 site_credential: 600 site_credential:
600 notice: 601 notice:
601 # added: 'Site credential for "%host%" added' 602 added: 'Identificant per "%host%" ajustat'
602 # updated: 'Site credential for "%host%" updated' 603 updated: 'Identificant per "%host%" mes a jorn'
603 # deleted: 'Site credential for "%host%" deleted' 604 deleted: 'Identificant per "%host%" suprimit'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index 00c559ed..c8e6cf6c 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -32,7 +32,7 @@ menu:
32 save_link: 'Zapisz link' 32 save_link: 'Zapisz link'
33 back_to_unread: 'Powrót do nieprzeczytanych artykułów' 33 back_to_unread: 'Powrót do nieprzeczytanych artykułów'
34 users_management: 'Zarządzanie użytkownikami' 34 users_management: 'Zarządzanie użytkownikami'
35 # site_credentials: 'Site credentials' 35 site_credentials: 'Poświadczenia strony'
36 top: 36 top:
37 add_new_entry: 'Dodaj nowy wpis' 37 add_new_entry: 'Dodaj nowy wpis'
38 search: 'Szukaj' 38 search: 'Szukaj'
@@ -94,7 +94,7 @@ config:
94 unread: 'Nieprzeczytane' 94 unread: 'Nieprzeczytane'
95 starred: 'Oznaczone gwiazdką' 95 starred: 'Oznaczone gwiazdką'
96 archive: 'Archiwum' 96 archive: 'Archiwum'
97 # all: 'All' 97 all: 'Wszystkie'
98 rss_limit: 'Link do RSS' 98 rss_limit: 'Link do RSS'
99 form_user: 99 form_user:
100 two_factor_description: "Włączenie autoryzacji dwuetapowej oznacza, że będziesz otrzymywał maile z kodem przy każdym nowym, niezaufanym połączeniu" 100 two_factor_description: "Włączenie autoryzacji dwuetapowej oznacza, że będziesz otrzymywał maile z kodem przy każdym nowym, niezaufanym połączeniu"
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: 'Filtrowane po tagach:' 169 filtered_tags: 'Filtrowane po tagach:'
170 filtered_search: 'Filtrowanie po wyszukiwaniu:' 170 filtered_search: 'Filtrowanie po wyszukiwaniu:'
171 untagged: 'Odtaguj wpisy' 171 untagged: 'Odtaguj wpisy'
172 all: 'Wszystkie przedmioty'
172 list: 173 list:
173 number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.' 174 number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.'
174 reading_time: 'szacunkowy czas czytania' 175 reading_time: 'szacunkowy czas czytania'
@@ -525,20 +526,20 @@ user:
525 placeholder: Filtruj po nazwie użytkownika lub adresie e-mail 526 placeholder: Filtruj po nazwie użytkownika lub adresie e-mail
526 527
527site_credential: 528site_credential:
528 # page_title: Site credentials management 529 page_title: Zardzanie poświadczeniami strony
529 # new_site_credential: Create a credential 530 new_site_credential: Stwórz nowe poświadczenie
530 # edit_site_credential: Edit an existing credential 531 edit_site_credential: Edytuj istniejące poświadczenie
531 # description: "Here you can manage all credentials for sites which required them (create, edit and delete), like a paywall, an authentication, etc." 532 description: "Tutaj możesz zarządzać wszystkim poświadczeniami wymaganymi przez strony (stwórz, edytuj i usuń ), takie jak paywall, autentykacja, itp."
532 list: 533 list:
533 actions: Akcje 534 actions: Akcje
534 edit_action: Edytuj 535 edit_action: Edytuj
535 yes: Tak 536 yes: Tak
536 no: Nie 537 no: Nie
537 # create_new_one: Create a new credential 538 create_new_one: Stwórz nowe poświadczenie
538 form: 539 form:
539 # username_label: 'Username' 540 username_label: 'Nazwa użytkownika'
540 # host_label: 'Host' 541 host_label: 'Host'
541 # password_label: 'Password' 542 password_label: 'Hasło'
542 save: Zapisz 543 save: Zapisz
543 delete: Usuń 544 delete: Usuń
544 delete_confirm: Jesteś pewien? 545 delete_confirm: Jesteś pewien?
@@ -598,6 +599,6 @@ flashes:
598 deleted: 'Użytkownik "%username%" usunięty' 599 deleted: 'Użytkownik "%username%" usunięty'
599 site_credential: 600 site_credential:
600 notice: 601 notice:
601 # added: 'Site credential for "%host%" added' 602 added: 'Poświadczenie dla "%host%" dodane'
602 # updated: 'Site credential for "%host%" updated' 603 updated: 'Poświadczenie dla "%host%" zaktualizowane'
603 # deleted: 'Site credential for "%host%" deleted' 604 deleted: 'Poświadczenie dla "%host%" usuniętę'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
index 4ab5f144..5c1ae058 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
@@ -169,6 +169,7 @@ entry:
169 filtered_tags: 'Filtrar por tags:' 169 filtered_tags: 'Filtrar por tags:'
170 # filtered_search: 'Filtered by search:' 170 # filtered_search: 'Filtered by search:'
171 untagged: 'Entradas sem tags' 171 untagged: 'Entradas sem tags'
172 # all: 'All entries'
172 list: 173 list:
173 number_on_the_page: '{0} Não existem entradas.|{1} Existe uma entrada.|]1,Inf[ Existem %count% entradas.' 174 number_on_the_page: '{0} Não existem entradas.|{1} Existe uma entrada.|]1,Inf[ Existem %count% entradas.'
174 reading_time: 'tempo estimado de leitura' 175 reading_time: 'tempo estimado de leitura'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index f16504ed..0d6f5f8e 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -169,6 +169,7 @@ entry:
169 # filtered_tags: 'Filtered by tags:' 169 # filtered_tags: 'Filtered by tags:'
170 # filtered_search: 'Filtered by search:' 170 # filtered_search: 'Filtered by search:'
171 # untagged: 'Untagged entries' 171 # untagged: 'Untagged entries'
172 # all: 'All entries'
172 list: 173 list:
173 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 174 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
174 reading_time: 'timp estimat de citire' 175 reading_time: 'timp estimat de citire'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index 90a140cd..87b5e200 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -169,6 +169,7 @@ entry:
169 # filtered_tags: 'Filtered by tags:' 169 # filtered_tags: 'Filtered by tags:'
170 # filtered_search: 'Filtered by search:' 170 # filtered_search: 'Filtered by search:'
171 # untagged: 'Untagged entries' 171 # untagged: 'Untagged entries'
172 # all: 'All entries'
172 list: 173 list:
173 number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.' 174 number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.'
174 reading_time: 'tahmini okuma süresi' 175 reading_time: 'tahmini okuma süresi'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig
index 3d20a6bc..f8723189 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig
@@ -35,9 +35,9 @@
35 {% if craue_setting('share_unmark') %}<li><a href="{{ craue_setting('unmark_url') }}/mark/add?url={{ entry.url|url_encode }}&amp;title={{entry.title|url_encode}}&amp;v=6" target="_blank" class="tool unmark icon-image icon-image--unmark" title="unmark"><span>unmark.it</span></a></li>{% endif %} 35 {% if craue_setting('share_unmark') %}<li><a href="{{ craue_setting('unmark_url') }}/mark/add?url={{ entry.url|url_encode }}&amp;title={{entry.title|url_encode}}&amp;v=6" target="_blank" class="tool unmark icon-image icon-image--unmark" title="unmark"><span>unmark.it</span></a></li>{% endif %}
36 {% if craue_setting('carrot') %}<li><a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" class="tool carrot icon-image icon-image--carrot" target="_blank" title="carrot"><span>Carrot</span></a></li>{% endif %} 36 {% if craue_setting('carrot') %}<li><a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" class="tool carrot icon-image icon-image--carrot" target="_blank" title="carrot"><span>Carrot</span></a></li>{% endif %}
37 {% if craue_setting('show_printlink') %}<li><a title="{{ 'entry.view.left_menu.print'|trans }}" class="tool icon icon-print" href="javascript: window.print();"><span>{{ 'entry.view.left_menu.print'|trans }}</span></a></li>{% endif %} 37 {% if craue_setting('show_printlink') %}<li><a title="{{ 'entry.view.left_menu.print'|trans }}" class="tool icon icon-print" href="javascript: window.print();"><span>{{ 'entry.view.left_menu.print'|trans }}</span></a></li>{% endif %}
38 {% if craue_setting('export_epub') %}<li><a href="?epub&amp;method=id&amp;value={{ entry.id }}" title="Generate ePub file">EPUB</a></li>{% endif %} 38 {% if craue_setting('export_epub') %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'epub' }) }}" title="Generate ePub file">EPUB</a></li>{% endif %}
39 {% if craue_setting('export_mobi') %}<li><a href="?mobi&amp;method=id&amp;value={{ entry.id }}" title="Generate Mobi file">MOBI</a></li>{% endif %} 39 {% if craue_setting('export_mobi') %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'mobi' }) }}" title="Generate Mobi file">MOBI</a></li>{% endif %}
40 {% if craue_setting('export_pdf') %}<li><a href="?pdf&amp;method=id&amp;value={{ entry.id }}" title="Generate PDF file">PDF</a></li>{% endif %} 40 {% if craue_setting('export_pdf') %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'pdf' }) }}" title="Generate PDF file">PDF</a></li>{% endif %}
41 <li><a href="mailto:hello@wallabag.org?subject=Wrong%20display%20in%20wallabag&amp;body={{ entry.url|url_encode }}" title="{{ 'entry.view.left_menu.problem.label'|trans }}" class="tool bad-display icon icon-delete"><span>{{ 'entry.view.left_menu.problem.label'|trans }}</span></a></li> 41 <li><a href="mailto:hello@wallabag.org?subject=Wrong%20display%20in%20wallabag&amp;body={{ entry.url|url_encode }}" title="{{ 'entry.view.left_menu.problem.label'|trans }}" class="tool bad-display icon icon-delete"><span>{{ 'entry.view.left_menu.problem.label'|trans }}</span></a></li>
42 </ul> 42 </ul>
43 </div> 43 </div>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig
index 654c1d2d..5c17e9f7 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig
@@ -5,7 +5,7 @@
5{% elseif currentRoute == 'archive' %} 5{% elseif currentRoute == 'archive' %}
6 {{ 'entry.page_titles.archived'|trans }} 6 {{ 'entry.page_titles.archived'|trans }}
7{% elseif currentRoute == 'all' %} 7{% elseif currentRoute == 'all' %}
8 {{ 'entry.page_titles.filtered'|trans }} 8 {{ isFiltered ? 'entry.page_titles.filtered'|trans : 'entry.page_titles.all'|trans }}
9{% elseif currentRoute == 'search' %} 9{% elseif currentRoute == 'search' %}
10 {{ 'entry.page_titles.filtered_search'|trans }} {{ filter }} 10 {{ 'entry.page_titles.filtered_search'|trans }} {{ filter }}
11{% elseif currentRoute == 'tag_entries' %} 11{% elseif currentRoute == 'tag_entries' %}
diff --git a/src/Wallabag/ImportBundle/Controller/WallabagController.php b/src/Wallabag/ImportBundle/Controller/WallabagController.php
index 7b61805b..6e6524b4 100644
--- a/src/Wallabag/ImportBundle/Controller/WallabagController.php
+++ b/src/Wallabag/ImportBundle/Controller/WallabagController.php
@@ -3,7 +3,9 @@
3namespace Wallabag\ImportBundle\Controller; 3namespace Wallabag\ImportBundle\Controller;
4 4
5use Symfony\Bundle\FrameworkBundle\Controller\Controller; 5use Symfony\Bundle\FrameworkBundle\Controller\Controller;
6use Symfony\Component\HttpFoundation\RedirectResponse;
6use Symfony\Component\HttpFoundation\Request; 7use Symfony\Component\HttpFoundation\Request;
8use Symfony\Component\HttpFoundation\Response;
7use Wallabag\ImportBundle\Form\Type\UploadImportType; 9use Wallabag\ImportBundle\Form\Type\UploadImportType;
8 10
9/** 11/**
diff --git a/src/Wallabag/ImportBundle/Import/BrowserImport.php b/src/Wallabag/ImportBundle/Import/BrowserImport.php
index f1195824..78077324 100644
--- a/src/Wallabag/ImportBundle/Import/BrowserImport.php
+++ b/src/Wallabag/ImportBundle/Import/BrowserImport.php
@@ -4,7 +4,6 @@ namespace Wallabag\ImportBundle\Import;
4 4
5use Wallabag\CoreBundle\Entity\Entry; 5use Wallabag\CoreBundle\Entity\Entry;
6use Wallabag\CoreBundle\Event\EntrySavedEvent; 6use Wallabag\CoreBundle\Event\EntrySavedEvent;
7use Wallabag\UserBundle\Entity\User;
8 7
9abstract class BrowserImport extends AbstractImport 8abstract class BrowserImport extends AbstractImport
10{ 9{
@@ -232,4 +231,6 @@ abstract class BrowserImport extends AbstractImport
232 231
233 return $importedEntry; 232 return $importedEntry;
234 } 233 }
234
235 abstract protected function prepareEntry(array $entry = []);
235} 236}
diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php
index b1d753d2..be693d3b 100644
--- a/src/Wallabag/UserBundle/Repository/UserRepository.php
+++ b/src/Wallabag/UserBundle/Repository/UserRepository.php
@@ -3,6 +3,8 @@
3namespace Wallabag\UserBundle\Repository; 3namespace Wallabag\UserBundle\Repository;
4 4
5use Doctrine\ORM\EntityRepository; 5use Doctrine\ORM\EntityRepository;
6use Doctrine\ORM\QueryBuilder;
7use Wallabag\UserBundle\Entity\User;
6 8
7class UserRepository extends EntityRepository 9class UserRepository extends EntityRepository
8{ 10{
@@ -54,6 +56,19 @@ class UserRepository extends EntityRepository
54 } 56 }
55 57
56 /** 58 /**
59 * Count how many users are existing.
60 *
61 * @return int
62 */
63 public function getSumUsers()
64 {
65 return $this->createQueryBuilder('u')
66 ->select('count(u)')
67 ->getQuery()
68 ->getSingleScalarResult();
69 }
70
71 /**
57 * Retrieves users filtered with a search term. 72 * Retrieves users filtered with a search term.
58 * 73 *
59 * @param string $term 74 * @param string $term
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml
index 53a1afd1..cebf8f28 100644
--- a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml
+++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml
@@ -5,7 +5,7 @@ auth_code:
5 subject: "Còdi d'autentificacion wallabag" 5 subject: "Còdi d'autentificacion wallabag"
6 body: 6 body:
7 hello: "Bonjorn %user%," 7 hello: "Bonjorn %user%,"
8 first_para: "Estant qu'avètz activat la dobla autentificacion sus vòtre compte wallabag e que venètz de vos conectar dempuèi un novèl aparelh (ordinador, mobil, etc.) vos mandem un còdi per validar la connexion." 8 first_para: "Estant qu'avètz activat l'autentificacion en dos temps sus vòstre compte wallabag e que venètz de vos connectar dempuèi un novèl periferic (ordinador, mobil, etc.) vos mandem un còdi per validar la connexion."
9 second_para: "Vaquí lo còdi a dintrar :" 9 second_para: "Vaquí lo còdi per dintrar :"
10 support: "S'avètz un problèma de connexion, dobtetz pas a contacter l'assisténcia : " 10 support: "S'avètz un problèma de connexion, dobtetz pas a contactar l'assisténcia : "
11 signature: "La còla de wallabag" 11 signature: "La còla de wallabag"
diff --git a/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php b/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php
index 25de2730..210b2ab6 100644
--- a/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php
+++ b/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php
@@ -55,7 +55,8 @@ class ExportCommandTest extends WallabagCoreTestCase
55 'username' => 'admin', 55 'username' => 'admin',
56 ]); 56 ]);
57 57
58 $this->assertContains('Exporting 5 entrie(s) for user « admin »... Done', $tester->getDisplay()); 58 $this->assertContains('Exporting 5 entrie(s) for user admin...', $tester->getDisplay());
59 $this->assertContains('Done', $tester->getDisplay());
59 $this->assertFileExists('admin-export.json'); 60 $this->assertFileExists('admin-export.json');
60 } 61 }
61 62
diff --git a/tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php b/tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php
new file mode 100644
index 00000000..9068cf59
--- /dev/null
+++ b/tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php
@@ -0,0 +1,75 @@
1<?php
2
3namespace Tests\Wallabag\CoreBundle\Command;
4
5use Symfony\Bundle\FrameworkBundle\Console\Application;
6use Symfony\Component\Console\Tester\CommandTester;
7use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
8use Wallabag\CoreBundle\Command\ListUserCommand;
9
10class ListUserCommandTest extends WallabagCoreTestCase
11{
12 public function testRunListUserCommand()
13 {
14 $application = new Application($this->getClient()->getKernel());
15 $application->add(new ListUserCommand());
16
17 $command = $application->find('wallabag:user:list');
18
19 $tester = new CommandTester($command);
20 $tester->execute([
21 'command' => $command->getName(),
22 ]);
23
24 $this->assertContains('3/3 user(s) displayed.', $tester->getDisplay());
25 }
26
27 public function testRunListUserCommandWithLimit()
28 {
29 $application = new Application($this->getClient()->getKernel());
30 $application->add(new ListUserCommand());
31
32 $command = $application->find('wallabag:user:list');
33
34 $tester = new CommandTester($command);
35 $tester->execute([
36 'command' => $command->getName(),
37 '--limit' => 2,
38 ]);
39
40 $this->assertContains('2/3 user(s) displayed.', $tester->getDisplay());
41 }
42
43 public function testRunListUserCommandWithSearch()
44 {
45 $application = new Application($this->getClient()->getKernel());
46 $application->add(new ListUserCommand());
47
48 $command = $application->find('wallabag:user:list');
49
50 $tester = new CommandTester($command);
51 $tester->execute([
52 'command' => $command->getName(),
53 'search' => 'boss',
54 ]);
55
56 $this->assertContains('1/3 (filtered) user(s) displayed.', $tester->getDisplay());
57 }
58
59 public function testRunListUserCommandWithSearchAndLimit()
60 {
61 $application = new Application($this->getClient()->getKernel());
62 $application->add(new ListUserCommand());
63
64 $command = $application->find('wallabag:user:list');
65
66 $tester = new CommandTester($command);
67 $tester->execute([
68 'command' => $command->getName(),
69 'search' => 'bo',
70 '--limit' => 1,
71 ]);
72
73 $this->assertContains('1/3 (filtered) user(s) displayed.', $tester->getDisplay());
74 }
75}
diff --git a/tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php b/tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php
new file mode 100644
index 00000000..63c068b4
--- /dev/null
+++ b/tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php
@@ -0,0 +1,115 @@
1<?php
2
3namespace Tests\Wallabag\CoreBundle\Command;
4
5use Symfony\Bundle\FrameworkBundle\Console\Application;
6use Symfony\Component\Console\Tester\CommandTester;
7use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
8use Wallabag\CoreBundle\Command\ReloadEntryCommand;
9use Wallabag\CoreBundle\Entity\Entry;
10
11class ReloadEntryCommandTest extends WallabagCoreTestCase
12{
13 public $url = 'http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html';
14
15 /**
16 * @var entry
17 */
18 public $adminEntry;
19
20 /**
21 * @var Entry
22 */
23 public $bobEntry;
24
25 public function setUp()
26 {
27 parent::setUp();
28
29 $userRepository = $this->getClient()->getContainer()->get('wallabag_user.user_repository');
30
31 $user = $userRepository->findOneByUserName('admin');
32 $this->adminEntry = new Entry($user);
33 $this->adminEntry->setUrl($this->url);
34 $this->adminEntry->setTitle('title foo');
35 $this->adminEntry->setContent('');
36 $this->getEntityManager()->persist($this->adminEntry);
37
38 $user = $userRepository->findOneByUserName('bob');
39 $this->bobEntry = new Entry($user);
40 $this->bobEntry->setUrl($this->url);
41 $this->bobEntry->setTitle('title foo');
42 $this->bobEntry->setContent('');
43 $this->getEntityManager()->persist($this->bobEntry);
44
45 $this->getEntityManager()->flush();
46 }
47
48 public function testRunReloadEntryCommand()
49 {
50 $application = new Application($this->getClient()->getKernel());
51 $application->add(new ReloadEntryCommand());
52
53 $command = $application->find('wallabag:entry:reload');
54 $tester = new CommandTester($command);
55 $tester->execute([
56 'command' => $command->getName(),
57 ], [
58 'interactive' => false,
59 ]);
60
61 $reloadedEntries = $this->getClient()
62 ->getContainer()
63 ->get('wallabag_core.entry_repository')
64 ->findById([$this->adminEntry->getId(), $this->bobEntry->getId()]);
65
66 foreach ($reloadedEntries as $reloadedEntry) {
67 $this->assertNotEmpty($reloadedEntry->getContent());
68 }
69
70 $this->assertContains('Done', $tester->getDisplay());
71 }
72
73 public function testRunReloadEntryWithUsernameCommand()
74 {
75 $application = new Application($this->getClient()->getKernel());
76 $application->add(new ReloadEntryCommand());
77
78 $command = $application->find('wallabag:entry:reload');
79 $tester = new CommandTester($command);
80 $tester->execute([
81 'command' => $command->getName(),
82 'username' => 'admin',
83 ], [
84 'interactive' => false,
85 ]);
86
87 $entryRepository = $this->getClient()->getContainer()->get('wallabag_core.entry_repository');
88
89 $reloadedAdminEntry = $entryRepository->find($this->adminEntry->getId());
90 $this->assertNotEmpty($reloadedAdminEntry->getContent());
91
92 $reloadedBobEntry = $entryRepository->find($this->bobEntry->getId());
93 $this->assertEmpty($reloadedBobEntry->getContent());
94
95 $this->assertContains('Done', $tester->getDisplay());
96 }
97
98 public function testRunReloadEntryWithoutEntryCommand()
99 {
100 $application = new Application($this->getClient()->getKernel());
101 $application->add(new ReloadEntryCommand());
102
103 $command = $application->find('wallabag:entry:reload');
104 $tester = new CommandTester($command);
105 $tester->execute([
106 'command' => $command->getName(),
107 'username' => 'empty',
108 ], [
109 'interactive' => false,
110 ]);
111
112 $this->assertContains('No entry to reload', $tester->getDisplay());
113 $this->assertNotContains('Done', $tester->getDisplay());
114 }
115}
diff --git a/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php b/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php
index c0a4acfa..9b34f2a0 100644
--- a/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php
+++ b/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php
@@ -56,9 +56,9 @@ class ShowUserCommandTest extends WallabagCoreTestCase
56 'username' => 'admin', 56 'username' => 'admin',
57 ]); 57 ]);
58 58
59 $this->assertContains('Username : admin', $tester->getDisplay()); 59 $this->assertContains('Username: admin', $tester->getDisplay());
60 $this->assertContains('Email : bigboss@wallabag.org', $tester->getDisplay()); 60 $this->assertContains('Email: bigboss@wallabag.org', $tester->getDisplay());
61 $this->assertContains('Display name : Big boss', $tester->getDisplay()); 61 $this->assertContains('Display name: Big boss', $tester->getDisplay());
62 $this->assertContains('2FA activated: no', $tester->getDisplay()); 62 $this->assertContains('2FA activated: no', $tester->getDisplay());
63 } 63 }
64 64
@@ -88,6 +88,6 @@ class ShowUserCommandTest extends WallabagCoreTestCase
88 'username' => 'admin', 88 'username' => 'admin',
89 ]); 89 ]);
90 90
91 $this->assertContains('Display name : Bug boss', $tester->getDisplay()); 91 $this->assertContains('Display name: Bug boss', $tester->getDisplay());
92 } 92 }
93} 93}
diff --git a/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php b/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php
index 96d0e91f..b1e56a10 100644
--- a/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php
+++ b/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php
@@ -55,6 +55,7 @@ class TagAllCommandTest extends WallabagCoreTestCase
55 'username' => 'admin', 55 'username' => 'admin',
56 ]); 56 ]);
57 57
58 $this->assertContains('Tagging entries for user « admin »... Done', $tester->getDisplay()); 58 $this->assertContains('Tagging entries for user admin...', $tester->getDisplay());
59 $this->assertContains('Done', $tester->getDisplay());
59 } 60 }
60} 61}