aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
authorJeremy Benoist <jeremy.benoist@gmail.com>2016-10-11 21:01:30 +0200
committerJeremy Benoist <jeremy.benoist@gmail.com>2016-10-11 21:01:30 +0200
commite4cf672ccf61689ba28c2e89fc55f83167800b18 (patch)
tree5dc22c97797bdcdd0a3d2a7e182410f04a748c1e /src/Wallabag
parente57df5611fe82ce61a71d51c762ee9296f18c3ac (diff)
parentdbe94e73a9eaf3acb250812913b0303b35d01a2e (diff)
downloadwallabag-e4cf672ccf61689ba28c2e89fc55f83167800b18.tar.gz
wallabag-e4cf672ccf61689ba28c2e89fc55f83167800b18.tar.zst
wallabag-e4cf672ccf61689ba28c2e89fc55f83167800b18.zip
Merge remote-tracking branch 'origin/master' into 2.2
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/ApiBundle/Controller/DeveloperController.php (renamed from src/Wallabag/CoreBundle/Controller/DeveloperController.php)4
-rw-r--r--src/Wallabag/ApiBundle/Controller/WallabagRestController.php52
-rw-r--r--src/Wallabag/ApiBundle/Entity/AccessToken.php2
-rw-r--r--src/Wallabag/ApiBundle/Entity/Client.php10
-rw-r--r--src/Wallabag/ApiBundle/Entity/RefreshToken.php2
-rw-r--r--src/Wallabag/ApiBundle/Form/Type/ClientType.php (renamed from src/Wallabag/CoreBundle/Form/Type/ClientType.php)2
-rw-r--r--src/Wallabag/CoreBundle/Command/InstallCommand.php17
-rw-r--r--src/Wallabag/CoreBundle/Command/TagAllCommand.php5
-rw-r--r--src/Wallabag/CoreBundle/Controller/TagController.php25
-rw-r--r--src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php8
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php20
-rw-r--r--src/Wallabag/CoreBundle/Repository/TagRepository.php10
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig1
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig11
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/common/Static/_bookmarklet.html.twig2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig17
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig2
31 files changed, 170 insertions, 48 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/DeveloperController.php b/src/Wallabag/ApiBundle/Controller/DeveloperController.php
index f3492b74..5a36a260 100644
--- a/src/Wallabag/CoreBundle/Controller/DeveloperController.php
+++ b/src/Wallabag/ApiBundle/Controller/DeveloperController.php
@@ -1,12 +1,12 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\Controller; 3namespace Wallabag\ApiBundle\Controller;
4 4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Symfony\Component\HttpFoundation\Request; 6use Symfony\Component\HttpFoundation\Request;
7use Symfony\Bundle\FrameworkBundle\Controller\Controller; 7use Symfony\Bundle\FrameworkBundle\Controller\Controller;
8use Wallabag\ApiBundle\Entity\Client; 8use Wallabag\ApiBundle\Entity\Client;
9use Wallabag\CoreBundle\Form\Type\ClientType; 9use Wallabag\ApiBundle\Form\Type\ClientType;
10 10
11class DeveloperController extends Controller 11class DeveloperController extends Controller
12{ 12{
diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
index a0d9d4f3..9997913d 100644
--- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
@@ -27,7 +27,8 @@ class WallabagRestController extends FOSRestController
27 * 27 *
28 * @ApiDoc( 28 * @ApiDoc(
29 * parameters={ 29 * parameters={
30 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"} 30 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
31 * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="Urls (as an array) to check if it exists"}
31 * } 32 * }
32 * ) 33 * )
33 * 34 *
@@ -37,6 +38,25 @@ class WallabagRestController extends FOSRestController
37 { 38 {
38 $this->validateAuthentication(); 39 $this->validateAuthentication();
39 40
41 $urls = $request->query->get('urls', []);
42
43 // handle multiple urls first
44 if (!empty($urls)) {
45 $results = [];
46 foreach ($urls as $url) {
47 $res = $this->getDoctrine()
48 ->getRepository('WallabagCoreBundle:Entry')
49 ->findByUrlAndUserId($url, $this->getUser()->getId());
50
51 $results[$url] = false === $res ? false : true;
52 }
53
54 $json = $this->get('serializer')->serialize($results, 'json');
55
56 return (new JsonResponse())->setJson($json);
57 }
58
59 // let's see if it is a simple url?
40 $url = $request->query->get('url', ''); 60 $url = $request->query->get('url', '');
41 61
42 if (empty($url)) { 62 if (empty($url)) {
@@ -367,7 +387,7 @@ class WallabagRestController extends FOSRestController
367 387
368 $tags = $this->getDoctrine() 388 $tags = $this->getDoctrine()
369 ->getRepository('WallabagCoreBundle:Tag') 389 ->getRepository('WallabagCoreBundle:Tag')
370 ->findAllTagsWithEntries($this->getUser()->getId()); 390 ->findAllTags($this->getUser()->getId());
371 391
372 $json = $this->get('serializer')->serialize($tags, 'json'); 392 $json = $this->get('serializer')->serialize($tags, 'json');
373 393
@@ -400,6 +420,8 @@ class WallabagRestController extends FOSRestController
400 ->getRepository('WallabagCoreBundle:Entry') 420 ->getRepository('WallabagCoreBundle:Entry')
401 ->removeTag($this->getUser()->getId(), $tag); 421 ->removeTag($this->getUser()->getId(), $tag);
402 422
423 $this->cleanOrphanTag($tag);
424
403 $json = $this->get('serializer')->serialize($tag, 'json'); 425 $json = $this->get('serializer')->serialize($tag, 'json');
404 426
405 return (new JsonResponse())->setJson($json); 427 return (new JsonResponse())->setJson($json);
@@ -440,6 +462,8 @@ class WallabagRestController extends FOSRestController
440 ->getRepository('WallabagCoreBundle:Entry') 462 ->getRepository('WallabagCoreBundle:Entry')
441 ->removeTags($this->getUser()->getId(), $tags); 463 ->removeTags($this->getUser()->getId(), $tags);
442 464
465 $this->cleanOrphanTag($tags);
466
443 $json = $this->get('serializer')->serialize($tags, 'json'); 467 $json = $this->get('serializer')->serialize($tags, 'json');
444 468
445 return (new JsonResponse())->setJson($json); 469 return (new JsonResponse())->setJson($json);
@@ -464,6 +488,8 @@ class WallabagRestController extends FOSRestController
464 ->getRepository('WallabagCoreBundle:Entry') 488 ->getRepository('WallabagCoreBundle:Entry')
465 ->removeTag($this->getUser()->getId(), $tag); 489 ->removeTag($this->getUser()->getId(), $tag);
466 490
491 $this->cleanOrphanTag($tag);
492
467 $json = $this->get('serializer')->serialize($tag, 'json'); 493 $json = $this->get('serializer')->serialize($tag, 'json');
468 494
469 return (new JsonResponse())->setJson($json); 495 return (new JsonResponse())->setJson($json);
@@ -486,6 +512,28 @@ class WallabagRestController extends FOSRestController
486 } 512 }
487 513
488 /** 514 /**
515 * Remove orphan tag in case no entries are associated to it.
516 *
517 * @param Tag|array $tags
518 */
519 private function cleanOrphanTag($tags)
520 {
521 if (!is_array($tags)) {
522 $tags = [$tags];
523 }
524
525 $em = $this->getDoctrine()->getManager();
526
527 foreach ($tags as $tag) {
528 if (count($tag->getEntries()) === 0) {
529 $em->remove($tag);
530 }
531 }
532
533 $em->flush();
534 }
535
536 /**
489 * Validate that the first id is equal to the second one. 537 * Validate that the first id is equal to the second one.
490 * If not, throw exception. It means a user try to access information from an other user. 538 * If not, throw exception. It means a user try to access information from an other user.
491 * 539 *
diff --git a/src/Wallabag/ApiBundle/Entity/AccessToken.php b/src/Wallabag/ApiBundle/Entity/AccessToken.php
index 2ff63a83..c09a0c80 100644
--- a/src/Wallabag/ApiBundle/Entity/AccessToken.php
+++ b/src/Wallabag/ApiBundle/Entity/AccessToken.php
@@ -19,7 +19,7 @@ class AccessToken extends BaseAccessToken
19 protected $id; 19 protected $id;
20 20
21 /** 21 /**
22 * @ORM\ManyToOne(targetEntity="Client") 22 * @ORM\ManyToOne(targetEntity="Client", inversedBy="accessTokens")
23 * @ORM\JoinColumn(nullable=false) 23 * @ORM\JoinColumn(nullable=false)
24 */ 24 */
25 protected $client; 25 protected $client;
diff --git a/src/Wallabag/ApiBundle/Entity/Client.php b/src/Wallabag/ApiBundle/Entity/Client.php
index 3e2f491c..f7898ac8 100644
--- a/src/Wallabag/ApiBundle/Entity/Client.php
+++ b/src/Wallabag/ApiBundle/Entity/Client.php
@@ -25,6 +25,16 @@ class Client extends BaseClient
25 */ 25 */
26 protected $name; 26 protected $name;
27 27
28 /**
29 * @ORM\OneToMany(targetEntity="RefreshToken", mappedBy="client", cascade={"remove"})
30 */
31 protected $refreshTokens;
32
33 /**
34 * @ORM\OneToMany(targetEntity="AccessToken", mappedBy="client", cascade={"remove"})
35 */
36 protected $accessTokens;
37
28 public function __construct() 38 public function __construct()
29 { 39 {
30 parent::__construct(); 40 parent::__construct();
diff --git a/src/Wallabag/ApiBundle/Entity/RefreshToken.php b/src/Wallabag/ApiBundle/Entity/RefreshToken.php
index 6d0cab68..822a02d8 100644
--- a/src/Wallabag/ApiBundle/Entity/RefreshToken.php
+++ b/src/Wallabag/ApiBundle/Entity/RefreshToken.php
@@ -19,7 +19,7 @@ class RefreshToken extends BaseRefreshToken
19 protected $id; 19 protected $id;
20 20
21 /** 21 /**
22 * @ORM\ManyToOne(targetEntity="Client") 22 * @ORM\ManyToOne(targetEntity="Client", inversedBy="refreshTokens")
23 * @ORM\JoinColumn(nullable=false) 23 * @ORM\JoinColumn(nullable=false)
24 */ 24 */
25 protected $client; 25 protected $client;
diff --git a/src/Wallabag/CoreBundle/Form/Type/ClientType.php b/src/Wallabag/ApiBundle/Form/Type/ClientType.php
index d1fa94e6..0ea1a9c5 100644
--- a/src/Wallabag/CoreBundle/Form/Type/ClientType.php
+++ b/src/Wallabag/ApiBundle/Form/Type/ClientType.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\ApiBundle\Form\Type;
4 4
5use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
6use Symfony\Component\Form\CallbackTransformer; 6use Symfony\Component\Form\CallbackTransformer;
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index 42982e4a..59110782 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -9,7 +9,7 @@ use Symfony\Component\Console\Helper\Table;
9use Symfony\Component\Console\Input\ArrayInput; 9use Symfony\Component\Console\Input\ArrayInput;
10use Symfony\Component\Console\Input\InputInterface; 10use Symfony\Component\Console\Input\InputInterface;
11use Symfony\Component\Console\Input\InputOption; 11use Symfony\Component\Console\Input\InputOption;
12use Symfony\Component\Console\Output\NullOutput; 12use Symfony\Component\Console\Output\BufferedOutput;
13use Symfony\Component\Console\Output\OutputInterface; 13use Symfony\Component\Console\Output\OutputInterface;
14use Symfony\Component\Console\Question\ConfirmationQuestion; 14use Symfony\Component\Console\Question\ConfirmationQuestion;
15use Symfony\Component\Console\Question\Question; 15use Symfony\Component\Console\Question\Question;
@@ -97,7 +97,8 @@ class InstallCommand extends ContainerAwareCommand
97 try { 97 try {
98 $this->getContainer()->get('doctrine')->getManager()->getConnection()->connect(); 98 $this->getContainer()->get('doctrine')->getManager()->getConnection()->connect();
99 } catch (\Exception $e) { 99 } catch (\Exception $e) {
100 if (false === strpos($e->getMessage(), 'Unknown database')) { 100 if (false === strpos($e->getMessage(), 'Unknown database')
101 && false === strpos($e->getMessage(), 'database "'.$this->getContainer()->getParameter('database_name').'" does not exist')) {
101 $fulfilled = false; 102 $fulfilled = false;
102 $status = '<error>ERROR!</error>'; 103 $status = '<error>ERROR!</error>';
103 $help = 'Can\'t connect to the database: '.$e->getMessage(); 104 $help = 'Can\'t connect to the database: '.$e->getMessage();
@@ -420,16 +421,18 @@ class InstallCommand extends ContainerAwareCommand
420 } 421 }
421 422
422 $this->getApplication()->setAutoExit(false); 423 $this->getApplication()->setAutoExit(false);
423 $exitCode = $this->getApplication()->run(new ArrayInput($parameters), new NullOutput()); 424
425 $output = new BufferedOutput();
426 $exitCode = $this->getApplication()->run(new ArrayInput($parameters), $output);
424 427
425 if (0 !== $exitCode) { 428 if (0 !== $exitCode) {
426 $this->getApplication()->setAutoExit(true); 429 $this->getApplication()->setAutoExit(true);
427 430
428 $errorMessage = sprintf('The command "%s" terminated with an error code: %u.', $command, $exitCode); 431 $this->defaultOutput->writeln('');
429 $this->defaultOutput->writeln("<error>$errorMessage</error>"); 432 $this->defaultOutput->writeln('<error>The command "'.$command.'" generates some errors: </error>');
430 $exception = new \Exception($errorMessage, $exitCode); 433 $this->defaultOutput->writeln($output->fetch());
431 434
432 throw $exception; 435 die();
433 } 436 }
434 437
435 // PDO does not always close the connection after Doctrine commands. 438 // PDO does not always close the connection after Doctrine commands.
diff --git a/src/Wallabag/CoreBundle/Command/TagAllCommand.php b/src/Wallabag/CoreBundle/Command/TagAllCommand.php
index db1a9ab7..3f9bb04d 100644
--- a/src/Wallabag/CoreBundle/Command/TagAllCommand.php
+++ b/src/Wallabag/CoreBundle/Command/TagAllCommand.php
@@ -34,10 +34,13 @@ class TagAllCommand extends ContainerAwareCommand
34 } 34 }
35 $tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger'); 35 $tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger');
36 36
37 $output->write(sprintf('Tagging entries for user « <info>%s</info> »... ', $user->getUserName())); 37 $output->write(sprintf('Tagging entries for user « <comment>%s</comment> »... ', $user->getUserName()));
38 38
39 $entries = $tagger->tagAllForUser($user); 39 $entries = $tagger->tagAllForUser($user);
40 40
41 $output->writeln('<info>Done.</info>');
42 $output->write(sprintf('Persist entries ... ', $user->getUserName()));
43
41 $em = $this->getDoctrine()->getManager(); 44 $em = $this->getDoctrine()->getManager();
42 foreach ($entries as $entry) { 45 foreach ($entries as $entry) {
43 $em->persist($entry); 46 $em->persist($entry);
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php
index 623a6146..5acc6852 100644
--- a/src/Wallabag/CoreBundle/Controller/TagController.php
+++ b/src/Wallabag/CoreBundle/Controller/TagController.php
@@ -63,10 +63,12 @@ class TagController extends Controller
63 $entry->removeTag($tag); 63 $entry->removeTag($tag);
64 $em = $this->getDoctrine()->getManager(); 64 $em = $this->getDoctrine()->getManager();
65 $em->flush(); 65 $em->flush();
66 if (count($tag->getEntries()) == 0) { 66
67 // remove orphan tag in case no entries are associated to it
68 if (count($tag->getEntries()) === 0) {
67 $em->remove($tag); 69 $em->remove($tag);
70 $em->flush();
68 } 71 }
69 $em->flush();
70 72
71 $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer')); 73 $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer'));
72 74
@@ -84,10 +86,25 @@ class TagController extends Controller
84 { 86 {
85 $tags = $this->getDoctrine() 87 $tags = $this->getDoctrine()
86 ->getRepository('WallabagCoreBundle:Tag') 88 ->getRepository('WallabagCoreBundle:Tag')
87 ->findAllTagsWithEntries($this->getUser()->getId()); 89 ->findAllTags($this->getUser()->getId());
90
91 $flatTags = [];
92
93 foreach ($tags as $key => $tag) {
94 $nbEntries = $this->getDoctrine()
95 ->getRepository('WallabagCoreBundle:Entry')
96 ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag['id']);
97
98 $flatTags[] = [
99 'id' => $tag['id'],
100 'label' => $tag['label'],
101 'slug' => $tag['slug'],
102 'nbEntries' => $nbEntries,
103 ];
104 }
88 105
89 return $this->render('WallabagCoreBundle:Tag:tags.html.twig', [ 106 return $this->render('WallabagCoreBundle:Tag:tags.html.twig', [
90 'tags' => $tags, 107 'tags' => $flatTags,
91 ]); 108 ]);
92 } 109 }
93 110
diff --git a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php
index 239d09ae..b490e209 100644
--- a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php
+++ b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php
@@ -55,6 +55,7 @@ class RuleBasedTagger
55 { 55 {
56 $rules = $this->getRulesForUser($user); 56 $rules = $this->getRulesForUser($user);
57 $entries = []; 57 $entries = [];
58 $tagsCache = [];
58 59
59 foreach ($rules as $rule) { 60 foreach ($rules as $rule) {
60 $qb = $this->entryRepository->getBuilderForAllByUser($user->getId()); 61 $qb = $this->entryRepository->getBuilderForAllByUser($user->getId());
@@ -62,7 +63,12 @@ class RuleBasedTagger
62 63
63 foreach ($entries as $entry) { 64 foreach ($entries as $entry) {
64 foreach ($rule->getTags() as $label) { 65 foreach ($rule->getTags() as $label) {
65 $tag = $this->getTag($label); 66 // avoid new tag duplicate by manually caching them
67 if (!isset($tagsCache[$label])) {
68 $tagsCache[$label] = $this->getTag($label);
69 }
70
71 $tag = $tagsCache[$label];
66 72
67 $entry->addTag($tag); 73 $entry->addTag($tag);
68 } 74 }
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index 75127b7d..cd2b47b9 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -309,4 +309,24 @@ class EntryRepository extends EntityRepository
309 309
310 return $qb->getQuery()->getSingleScalarResult(); 310 return $qb->getQuery()->getSingleScalarResult();
311 } 311 }
312
313 /**
314 * Count all entries for a tag and a user.
315 *
316 * @param int $userId
317 * @param int $tagId
318 *
319 * @return int
320 */
321 public function countAllEntriesByUserIdAndTagId($userId, $tagId)
322 {
323 $qb = $this->createQueryBuilder('e')
324 ->select('count(e.id)')
325 ->leftJoin('e.tags', 't')
326 ->where('e.user=:userId')->setParameter('userId', $userId)
327 ->andWhere('t.id=:tagId')->setParameter('tagId', $tagId)
328 ;
329
330 return $qb->getQuery()->getSingleScalarResult();
331 }
312} 332}
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php
index 9d127da7..e76878d4 100644
--- a/src/Wallabag/CoreBundle/Repository/TagRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php
@@ -33,19 +33,23 @@ class TagRepository extends EntityRepository
33 } 33 }
34 34
35 /** 35 /**
36 * Find all tags with associated entries per user. 36 * Find all tags per user.
37 * 37 *
38 * @param int $userId 38 * @param int $userId
39 * 39 *
40 * @return array 40 * @return array
41 */ 41 */
42 public function findAllTagsWithEntries($userId) 42 public function findAllTags($userId)
43 { 43 {
44 return $this->createQueryBuilder('t') 44 return $this->createQueryBuilder('t')
45 ->select('t.slug', 't.label', 't.id')
45 ->leftJoin('t.entries', 'e') 46 ->leftJoin('t.entries', 'e')
46 ->where('e.user = :userId')->setParameter('userId', $userId) 47 ->where('e.user = :userId')->setParameter('userId', $userId)
48 ->groupBy('t.slug')
49 ->addGroupBy('t.label')
50 ->addGroupBy('t.id')
47 ->getQuery() 51 ->getQuery()
48 ->getResult(); 52 ->getArrayResult();
49 } 53 }
50 54
51 /** 55 /**
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index fb97454e..a4b727f4 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -29,7 +29,7 @@ services:
29 arguments: 29 arguments:
30 - "@doctrine" 30 - "@doctrine"
31 31
32 wallabag_core.table_prefix_subscriber: 32 wallabag_core.subscriber.table_prefix:
33 class: Wallabag\CoreBundle\Subscriber\TablePrefixSubscriber 33 class: Wallabag\CoreBundle\Subscriber\TablePrefixSubscriber
34 arguments: 34 arguments:
35 - "%database_table_prefix%" 35 - "%database_table_prefix%"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index 2de5d7bd..f5548a21 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -200,7 +200,7 @@ entry:
200 description: 'Vises artiklen forkert?' 200 description: 'Vises artiklen forkert?'
201 edit_title: 'Rediger titel' 201 edit_title: 'Rediger titel'
202 original_article: 'original' 202 original_article: 'original'
203 # annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %nbAnnotations% annotations' 203 # annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
204 created_at: 'Oprettelsesdato' 204 created_at: 'Oprettelsesdato'
205 new: 205 new:
206 page_title: 'Gem ny artikel' 206 page_title: 'Gem ny artikel'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index 515d43a0..9edd7fb7 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -200,7 +200,7 @@ entry:
200 description: 'Erscheint dieser Artikel falsch?' 200 description: 'Erscheint dieser Artikel falsch?'
201 edit_title: 'Titel ändern' 201 edit_title: 'Titel ändern'
202 original_article: 'original' 202 original_article: 'original'
203 annotations_on_the_entry: '{0} Keine Anmerkungen|{1} Eine Anmerkung|]1,Inf[ %nbAnnotations% Anmerkungen' 203 annotations_on_the_entry: '{0} Keine Anmerkungen|{1} Eine Anmerkung|]1,Inf[ %count% Anmerkungen'
204 created_at: 'Erstellungsdatum' 204 created_at: 'Erstellungsdatum'
205 new: 205 new:
206 page_title: 'Neuen Artikel speichern' 206 page_title: 'Neuen Artikel speichern'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 43f5a950..b86145a0 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -200,7 +200,7 @@ entry:
200 description: 'Does this article appear wrong?' 200 description: 'Does this article appear wrong?'
201 edit_title: 'Edit title' 201 edit_title: 'Edit title'
202 original_article: 'original' 202 original_article: 'original'
203 annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %nbAnnotations% annotations' 203 annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
204 created_at: 'Creation date' 204 created_at: 'Creation date'
205 new: 205 new:
206 page_title: 'Save new entry' 206 page_title: 'Save new entry'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index adeab2b0..b7187f50 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -200,7 +200,7 @@ entry:
200 description: '¿Este artículo no se muestra bien?' 200 description: '¿Este artículo no se muestra bien?'
201 edit_title: 'Modificar el título' 201 edit_title: 'Modificar el título'
202 original_article: 'original' 202 original_article: 'original'
203 annotations_on_the_entry: '{0} Sin anotaciones|{1} Una anotación|]1,Inf[ %nbAnnotations% anotaciones' 203 annotations_on_the_entry: '{0} Sin anotaciones|{1} Una anotación|]1,Inf[ %count% anotaciones'
204 created_at: 'Fecha de creación' 204 created_at: 'Fecha de creación'
205 new: 205 new:
206 page_title: 'Guardar un nuevo artículo' 206 page_title: 'Guardar un nuevo artículo'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 1c32a77c..8d19ccb1 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -200,7 +200,7 @@ entry:
200 description: "Est-ce que cet article s'affiche mal ?" 200 description: "Est-ce que cet article s'affiche mal ?"
201 edit_title: 'Modifier le titre' 201 edit_title: 'Modifier le titre'
202 original_article: 'original' 202 original_article: 'original'
203 annotations_on_the_entry: '{0} Aucune annotation|{1} Une annotation|]1,Inf[ %nbAnnotations% annotations' 203 annotations_on_the_entry: '{0} Aucune annotation|{1} Une annotation|]1,Inf[ %count% annotations'
204 created_at: 'Date de création' 204 created_at: 'Date de création'
205 new: 205 new:
206 page_title: 'Sauvegarder un nouvel article' 206 page_title: 'Sauvegarder un nouvel article'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index f662bd55..4d3452ea 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -200,7 +200,7 @@ entry:
200 description: 'Questo contenuto viene visualizzato male?' 200 description: 'Questo contenuto viene visualizzato male?'
201 edit_title: 'Modifica titolo' 201 edit_title: 'Modifica titolo'
202 original_article: 'originale' 202 original_article: 'originale'
203 annotations_on_the_entry: '{0} Nessuna annotazione|{1} Una annotazione|]1,Inf[ %nbAnnotations% annotazioni' 203 annotations_on_the_entry: '{0} Nessuna annotazione|{1} Una annotazione|]1,Inf[ %count% annotazioni'
204 created_at: 'Data di creazione' 204 created_at: 'Data di creazione'
205 new: 205 new:
206 page_title: 'Salva un nuovo contenuto' 206 page_title: 'Salva un nuovo contenuto'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index d81fb05e..f14213c6 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -200,7 +200,7 @@ entry:
200 description: "Marca mal la presentacion d'aqueste article ?" 200 description: "Marca mal la presentacion d'aqueste article ?"
201 edit_title: 'Modificar lo títol' 201 edit_title: 'Modificar lo títol'
202 original_article: 'original' 202 original_article: 'original'
203 annotations_on_the_entry: "{0} Pas cap d'anotacion|{1} Una anotacion|]1,Inf[ %nbAnnotations% anotacions" 203 annotations_on_the_entry: "{0} Pas cap d'anotacion|{1} Una anotacion|]1,Inf[ %count% anotacions"
204 created_at: 'Data de creacion' 204 created_at: 'Data de creacion'
205 new: 205 new:
206 page_title: 'Enregistrar un novèl article' 206 page_title: 'Enregistrar un novèl article'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index 9877d59a..a2fe13db 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -200,7 +200,7 @@ entry:
200 description: 'Czy ten artykuł wygląda źle?' 200 description: 'Czy ten artykuł wygląda źle?'
201 edit_title: 'Edytuj tytuł' 201 edit_title: 'Edytuj tytuł'
202 original_article: 'oryginalny' 202 original_article: 'oryginalny'
203 annotations_on_the_entry: '{0} Nie ma adnotacji |{1} Jedna adnotacja |]1,Inf[ %nbAnnotations% adnotacji' 203 annotations_on_the_entry: '{0} Nie ma adnotacji |{1} Jedna adnotacja |]1,Inf[ %count% adnotacji'
204 created_at: 'Czas stworzenia' 204 created_at: 'Czas stworzenia'
205 new: 205 new:
206 page_title: 'Zapisz nowy wpis' 206 page_title: 'Zapisz nowy wpis'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index 83246ed3..29db9c3e 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -200,7 +200,7 @@ entry:
200 description: 'Îți pare ciudat articolul?' 200 description: 'Îți pare ciudat articolul?'
201 edit_title: 'Editează titlul' 201 edit_title: 'Editează titlul'
202 original_article: 'original' 202 original_article: 'original'
203 # annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %nbAnnotations% annotations' 203 # annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
204 created_at: 'Data creării' 204 created_at: 'Data creării'
205 new: 205 new:
206 page_title: 'Salvează un nou articol' 206 page_title: 'Salvează un nou articol'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index 24dd6ff8..41e8e576 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -199,7 +199,7 @@ entry:
199 description: 'Bu makalede herhangi bir yanlışlık mı var?' 199 description: 'Bu makalede herhangi bir yanlışlık mı var?'
200 edit_title: 'Başlığı düzenle' 200 edit_title: 'Başlığı düzenle'
201 original_article: 'orijinal' 201 original_article: 'orijinal'
202 # annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %nbAnnotations% annotations' 202 # annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
203 created_at: 'Oluşturulma tarihi' 203 created_at: 'Oluşturulma tarihi'
204 new: 204 new:
205 page_title: 'Yeni makaleyi kaydet' 205 page_title: 'Yeni makaleyi kaydet'
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 b1aabf9b..3689159b 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
@@ -54,7 +54,6 @@
54 {% endif %} 54 {% endif %}
55 </i> 55 </i>
56 56
57 {% set nbAnnotations = entry.annotations | length %}
58 <span class="tool link"><i class="material-icons link">comment</i> {{ 'entry.view.annotations_on_the_entry'|transchoice(entry.annotations | length) }}</span> 57 <span class="tool link"><i class="material-icons link">comment</i> {{ 'entry.view.annotations_on_the_entry'|transchoice(entry.annotations | length) }}</span>
59 <aside class="tags"> 58 <aside class="tags">
60 <div class="card-entry-tags"> 59 <div class="card-entry-tags">
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig
index 50043907..1e2c6b42 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig
@@ -9,7 +9,7 @@
9 9
10 <ul> 10 <ul>
11 {% for tag in tags %} 11 {% for tag in tags %}
12 <li id="tag-{{ tag.id|e }}"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.entries.getValues | length }})</a></li> 12 <li id="tag-{{ tag.id|e }}"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.nbEntries | length }})</a></li>
13 {% endfor %} 13 {% endfor %}
14 </ul> 14 </ul>
15 15
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig
index a0a0d3c3..804adb36 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig
@@ -30,11 +30,16 @@
30 <meta property="og:title" content="{{ entry.title | raw }}" /> 30 <meta property="og:title" content="{{ entry.title | raw }}" />
31 <meta property="og:type" content="article" /> 31 <meta property="og:type" content="article" />
32 <meta property="og:url" content="{{ app.request.uri }}" /> 32 <meta property="og:url" content="{{ app.request.uri }}" />
33 {% set picturePath = app.request.schemeAndHttpHost ~ asset('bundles/wallabagcore/themes/_global/img/logo-other_themes.png') %}
33 {% if entry.previewPicture is not null %} 34 {% if entry.previewPicture is not null %}
34 <meta property="og:image" content="{{ entry.previewPicture }}" /> 35 {% set picturePath = entry.previewPicture %}
35 {% else %}
36 <meta property="og:image" content="{{ app.request.schemeAndHttpHost }}{{ asset('bundles/wallabagcore/themes/_global/img/logo-other_themes.png') }}" />
37 {% endif %} 36 {% endif %}
37 <meta property="og:image" content="{{ picturePath }}" />
38 <meta name="twitter:card" content="summary" />
39 <meta name="twitter:image" content="{{ picturePath }}" />
40 <meta name="twitter:site" content="@wallabagapp" />
41 <meta name="twitter:title" content="{{ entry.title | raw }}" />
42 <meta name="twitter:description" content="{{ entry.title | raw }}" />
38 </head> 43 </head>
39 <body> 44 <body>
40 <header> 45 <header>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/_bookmarklet.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/_bookmarklet.html.twig
index 966a84db..3385cd53 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/_bookmarklet.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/_bookmarklet.html.twig
@@ -1 +1 @@
<a id="bookmarklet" ondragend="this.click();" href="javascript:var url=location.href||url;var wllbg=window.open('{{ url('bookmarklet') }}?url=' + encodeURI(url),'_blank');wllbg.close();void(0);">bag it!</a> <a id="bookmarklet" ondragend="this.click();" href="javascript:(function(){var url=location.href||url;var wllbg=window.open('{{ url('bookmarklet') }}?url=' + encodeURI(url),'_blank');})();">bag it!</a>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
index 55b3ee5c..919f94ec 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
@@ -77,7 +77,7 @@
77 <div class="card-action"> 77 <div class="card-action">
78 <span class="bold"> 78 <span class="bold">
79 <a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.list.original_article'|trans }}: {{ entry.title|e }} - {{ entry.domainName|removeWww }}" class="tool original grey-text"><span>{{ entry.domainName|removeWww|truncate(18) }}</span></a> 79 <a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.list.original_article'|trans }}: {{ entry.title|e }} - {{ entry.domainName|removeWww }}" class="tool original grey-text"><span>{{ entry.domainName|removeWww|truncate(18) }}</span></a>
80 </bold> 80 </span>
81 81
82 <ul class="tools right"> 82 <ul class="tools right">
83 <li> 83 <li>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig
index 1ddb5a15..5188eb01 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig
@@ -225,7 +225,7 @@
225 <a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.view.original_article'|trans }} : {{ entry.title|e }}" class="tool"> 225 <a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.view.original_article'|trans }} : {{ entry.title|e }}" class="tool">
226 <i class="material-icons link">link</i> <span class="link">{{ entry.domainName|removeWww }}</span> 226 <i class="material-icons link">link</i> <span class="link">{{ entry.domainName|removeWww }}</span>
227 </a> 227 </a>
228 <span class="tool"><i class="material-icons link">comment</i> <span class="link">{{ 'entry.view.annotations_on_the_entry'|transchoice(entry.annotations | length) }}</span> 228 <span class="tool"><i class="material-icons link">comment</i></span> <span class="link">{{ 'entry.view.annotations_on_the_entry'|transchoice(entry.annotations | length) }}</span>
229 <div id="list"> 229 <div id="list">
230 {% for tag in entry.tags %} 230 {% for tag in entry.tags %}
231 <div class="chip"> 231 <div class="chip">
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig
index 1690633a..96f4f990 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig
@@ -6,12 +6,19 @@
6 <div class="results clearfix"> 6 <div class="results clearfix">
7 <div class="nb-results left">{{ 'tag.list.number_on_the_page'|transchoice(tags|length) }}</div> 7 <div class="nb-results left">{{ 'tag.list.number_on_the_page'|transchoice(tags|length) }}</div>
8 </div> 8 </div>
9
9 <br /> 10 <br />
10 <ul class="row data"> 11
11 {% for tag in tags %} 12 <div class="row">
12 <li id="tag-{{ tag.id|e }}" class="col l4 m6 s12"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.entries.getValues | length }})</a></li> 13 <ul class="card-tag-labels">
13 {% endfor %} 14 {% for tag in tags %}
14 </ul> 15 <li title="{{tag.label}} ({{ tag.nbEntries }})" id="tag-{{ tag.id }}" class="col l2 m2 s2">
16 <a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.nbEntries }})</a>
17 </li>
18 {% endfor %}
19 </ul>
20 </div>
21
15 <div> 22 <div>
16 <a href="{{ path('untagged') }}">{{ 'tag.list.see_untagged_entries'|trans }}</a> 23 <a href="{{ path('untagged') }}">{{ 'tag.list.see_untagged_entries'|trans }}</a>
17 </div> 24 </div>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
index c7d6d70d..de0049d3 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
@@ -73,7 +73,7 @@
73 <a class="waves-effect" href="{{ path('howto') }}">{{ 'menu.left.howto'|trans }}</a> 73 <a class="waves-effect" href="{{ path('howto') }}">{{ 'menu.left.howto'|trans }}</a>
74 </li> 74 </li>
75 <li class="bold"> 75 <li class="bold">
76 <a class="waves-effect" class="icon icon-power" href="{{ path('fos_user_security_logout') }}">{{ 'menu.left.logout'|trans }}</a> 76 <a class="waves-effect icon icon-power" href="{{ path('fos_user_security_logout') }}">{{ 'menu.left.logout'|trans }}</a>
77 </li> 77 </li>
78 </ul> 78 </ul>
79 <div class="nav-wrapper nav-panels"> 79 <div class="nav-wrapper nav-panels">