]> git.immae.eu Git - github/wallabag/wallabag.git/blob - src/Wallabag/CoreBundle/Twig/WallabagExtension.php
Merge pull request #4264 from herrriehm/master
[github/wallabag/wallabag.git] / src / Wallabag / CoreBundle / Twig / WallabagExtension.php
1 <?php
2
3 namespace Wallabag\CoreBundle\Twig;
4
5 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
6 use Symfony\Component\Translation\TranslatorInterface;
7 use Twig\Extension\AbstractExtension;
8 use Twig\Extension\GlobalsInterface;
9 use Twig\TwigFilter;
10 use Twig\TwigFunction;
11 use Wallabag\CoreBundle\Repository\EntryRepository;
12 use Wallabag\CoreBundle\Repository\TagRepository;
13
14 class WallabagExtension extends AbstractExtension implements GlobalsInterface
15 {
16 private $tokenStorage;
17 private $entryRepository;
18 private $tagRepository;
19 private $lifeTime;
20 private $translator;
21
22 public function __construct(EntryRepository $entryRepository, TagRepository $tagRepository, TokenStorageInterface $tokenStorage, $lifeTime, TranslatorInterface $translator)
23 {
24 $this->entryRepository = $entryRepository;
25 $this->tagRepository = $tagRepository;
26 $this->tokenStorage = $tokenStorage;
27 $this->lifeTime = $lifeTime;
28 $this->translator = $translator;
29 }
30
31 public function getGlobals()
32 {
33 return [];
34 }
35
36 public function getFilters()
37 {
38 return [
39 new TwigFilter('removeWww', [$this, 'removeWww']),
40 new TwigFilter('removeScheme', [$this, 'removeScheme']),
41 new TwigFilter('removeSchemeAndWww', [$this, 'removeSchemeAndWww']),
42 ];
43 }
44
45 public function getFunctions()
46 {
47 return [
48 new TwigFunction('count_entries', [$this, 'countEntries']),
49 new TwigFunction('count_tags', [$this, 'countTags']),
50 new TwigFunction('display_stats', [$this, 'displayStats']),
51 ];
52 }
53
54 public function removeWww($url)
55 {
56 return preg_replace('/^www\./i', '', $url);
57 }
58
59 public function removeScheme($url)
60 {
61 return preg_replace('#^https?://#i', '', $url);
62 }
63
64 public function removeSchemeAndWww($url)
65 {
66 return $this->removeWww($this->removeScheme($url));
67 }
68
69 /**
70 * Return number of entries depending of the type (unread, archive, starred or all).
71 *
72 * @param string $type Type of entries to count
73 *
74 * @return int
75 */
76 public function countEntries($type)
77 {
78 $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
79
80 if (null === $user || !\is_object($user)) {
81 return 0;
82 }
83
84 switch ($type) {
85 case 'starred':
86 $qb = $this->entryRepository->getBuilderForStarredByUser($user->getId());
87 break;
88 case 'archive':
89 $qb = $this->entryRepository->getBuilderForArchiveByUser($user->getId());
90 break;
91 case 'unread':
92 $qb = $this->entryRepository->getBuilderForUnreadByUser($user->getId());
93 break;
94 case 'all':
95 $qb = $this->entryRepository->getBuilderForAllByUser($user->getId());
96 break;
97 default:
98 throw new \InvalidArgumentException(sprintf('Type "%s" is not implemented.', $type));
99 }
100
101 // THANKS to PostgreSQL we CAN'T make a DEAD SIMPLE count(e.id)
102 // ERROR: column "e0_.id" must appear in the GROUP BY clause or be used in an aggregate function
103 $query = $qb
104 ->select('e.id')
105 ->groupBy('e.id')
106 ->getQuery();
107
108 $query->useQueryCache(true);
109 $query->useResultCache(true);
110 $query->setResultCacheLifetime($this->lifeTime);
111
112 return \count($query->getArrayResult());
113 }
114
115 /**
116 * Return number of tags.
117 *
118 * @return int
119 */
120 public function countTags()
121 {
122 $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
123
124 if (null === $user || !\is_object($user)) {
125 return 0;
126 }
127
128 return $this->tagRepository->countAllTags($user->getId());
129 }
130
131 /**
132 * Display a single line about reading stats.
133 *
134 * @return string
135 */
136 public function displayStats()
137 {
138 $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
139
140 if (null === $user || !\is_object($user)) {
141 return 0;
142 }
143
144 $query = $this->entryRepository->getBuilderForArchiveByUser($user->getId())
145 ->select('e.id')
146 ->groupBy('e.id')
147 ->getQuery();
148
149 $query->useQueryCache(true);
150 $query->useResultCache(true);
151 $query->setResultCacheLifetime($this->lifeTime);
152
153 $nbArchives = \count($query->getArrayResult());
154
155 $interval = $user->getCreatedAt()->diff(new \DateTime('now'));
156 $nbDays = (int) $interval->format('%a') ?: 1;
157
158 // force setlocale for date translation
159 setlocale(LC_TIME, strtolower($user->getConfig()->getLanguage()) . '_' . strtoupper(strtolower($user->getConfig()->getLanguage())));
160
161 return $this->translator->trans('footer.stats', [
162 '%user_creation%' => strftime('%e %B %Y', $user->getCreatedAt()->getTimestamp()),
163 '%nb_archives%' => $nbArchives,
164 '%per_day%' => round($nbArchives / $nbDays, 2),
165 ]);
166 }
167
168 public function getName()
169 {
170 return 'wallabag_extension';
171 }
172 }