diff options
Diffstat (limited to 'src/Wallabag/CoreBundle')
22 files changed, 153 insertions, 53 deletions
diff --git a/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php index b58909db..99170967 100644 --- a/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php +++ b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php | |||
@@ -51,7 +51,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand | |||
51 | } else { | 51 | } else { |
52 | $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll(); | 52 | $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll(); |
53 | 53 | ||
54 | $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', count($users))); | 54 | $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', \count($users))); |
55 | 55 | ||
56 | foreach ($users as $user) { | 56 | foreach ($users as $user) { |
57 | $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername())); | 57 | $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername())); |
@@ -79,7 +79,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand | |||
79 | $url = $this->similarUrl($entry['url']); | 79 | $url = $this->similarUrl($entry['url']); |
80 | 80 | ||
81 | /* @var $entry Entry */ | 81 | /* @var $entry Entry */ |
82 | if (in_array($url, $urls, true)) { | 82 | if (\in_array($url, $urls, true)) { |
83 | ++$duplicatesCount; | 83 | ++$duplicatesCount; |
84 | 84 | ||
85 | $em->remove($repo->find($entry['id'])); | 85 | $em->remove($repo->find($entry['id'])); |
@@ -96,8 +96,8 @@ class CleanDuplicatesCommand extends ContainerAwareCommand | |||
96 | 96 | ||
97 | private function similarUrl($url) | 97 | private function similarUrl($url) |
98 | { | 98 | { |
99 | if (in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls | 99 | if (\in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls |
100 | return substr($url, 0, strlen($url)); | 100 | return substr($url, 0, \strlen($url)); |
101 | } | 101 | } |
102 | 102 | ||
103 | return $url; | 103 | return $url; |
diff --git a/src/Wallabag/CoreBundle/Command/ExportCommand.php b/src/Wallabag/CoreBundle/Command/ExportCommand.php index 75e9ad91..128f9d65 100644 --- a/src/Wallabag/CoreBundle/Command/ExportCommand.php +++ b/src/Wallabag/CoreBundle/Command/ExportCommand.php | |||
@@ -47,7 +47,7 @@ class ExportCommand extends ContainerAwareCommand | |||
47 | ->getQuery() | 47 | ->getQuery() |
48 | ->getResult(); | 48 | ->getResult(); |
49 | 49 | ||
50 | $io->text(sprintf('Exporting <info>%d</info> entrie(s) for user <info>%s</info>...', count($entries), $user->getUserName())); | 50 | $io->text(sprintf('Exporting <info>%d</info> entrie(s) for user <info>%s</info>...', \count($entries), $user->getUserName())); |
51 | 51 | ||
52 | $filePath = $input->getArgument('filepath'); | 52 | $filePath = $input->getArgument('filepath'); |
53 | 53 | ||
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index a56a3257..3c76545c 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php | |||
@@ -81,7 +81,7 @@ class InstallCommand extends ContainerAwareCommand | |||
81 | $status = '<info>OK!</info>'; | 81 | $status = '<info>OK!</info>'; |
82 | $help = ''; | 82 | $help = ''; |
83 | 83 | ||
84 | if (!extension_loaded($this->getContainer()->getParameter('database_driver'))) { | 84 | if (!\extension_loaded($this->getContainer()->getParameter('database_driver'))) { |
85 | $fulfilled = false; | 85 | $fulfilled = false; |
86 | $status = '<error>ERROR!</error>'; | 86 | $status = '<error>ERROR!</error>'; |
87 | $help = 'Database driver "' . $this->getContainer()->getParameter('database_driver') . '" is not installed.'; | 87 | $help = 'Database driver "' . $this->getContainer()->getParameter('database_driver') . '" is not installed.'; |
@@ -146,7 +146,7 @@ class InstallCommand extends ContainerAwareCommand | |||
146 | $status = '<info>OK!</info>'; | 146 | $status = '<info>OK!</info>'; |
147 | $help = ''; | 147 | $help = ''; |
148 | 148 | ||
149 | if (!function_exists($functionRequired)) { | 149 | if (!\function_exists($functionRequired)) { |
150 | $fulfilled = false; | 150 | $fulfilled = false; |
151 | $status = '<error>ERROR!</error>'; | 151 | $status = '<error>ERROR!</error>'; |
152 | $help = 'You need the ' . $functionRequired . ' function activated'; | 152 | $help = 'You need the ' . $functionRequired . ' function activated'; |
@@ -371,7 +371,7 @@ class InstallCommand extends ContainerAwareCommand | |||
371 | } | 371 | } |
372 | 372 | ||
373 | try { | 373 | try { |
374 | return in_array($databaseName, $schemaManager->listDatabases(), true); | 374 | return \in_array($databaseName, $schemaManager->listDatabases(), true); |
375 | } catch (\Doctrine\DBAL\Exception\DriverException $e) { | 375 | } catch (\Doctrine\DBAL\Exception\DriverException $e) { |
376 | // it means we weren't able to get database list, assume the database doesn't exist | 376 | // it means we weren't able to get database list, assume the database doesn't exist |
377 | 377 | ||
@@ -389,6 +389,6 @@ class InstallCommand extends ContainerAwareCommand | |||
389 | { | 389 | { |
390 | $schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager(); | 390 | $schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager(); |
391 | 391 | ||
392 | return count($schemaManager->listTableNames()) > 0 ? true : false; | 392 | return \count($schemaManager->listTableNames()) > 0 ? true : false; |
393 | } | 393 | } |
394 | } | 394 | } |
diff --git a/src/Wallabag/CoreBundle/Command/ListUserCommand.php b/src/Wallabag/CoreBundle/Command/ListUserCommand.php index 68e515da..a7101a02 100644 --- a/src/Wallabag/CoreBundle/Command/ListUserCommand.php +++ b/src/Wallabag/CoreBundle/Command/ListUserCommand.php | |||
@@ -50,7 +50,7 @@ class ListUserCommand extends ContainerAwareCommand | |||
50 | $io->success( | 50 | $io->success( |
51 | sprintf( | 51 | sprintf( |
52 | '%s/%s%s user(s) displayed.', | 52 | '%s/%s%s user(s) displayed.', |
53 | count($users), | 53 | \count($users), |
54 | $nbUsers, | 54 | $nbUsers, |
55 | null === $input->getArgument('search') ? '' : ' (filtered)' | 55 | null === $input->getArgument('search') ? '' : ' (filtered)' |
56 | ) | 56 | ) |
diff --git a/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php b/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php index 91998841..10918872 100644 --- a/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php +++ b/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php | |||
@@ -43,7 +43,7 @@ class ReloadEntryCommand extends ContainerAwareCommand | |||
43 | $entryRepository = $this->getContainer()->get('wallabag_core.entry_repository'); | 43 | $entryRepository = $this->getContainer()->get('wallabag_core.entry_repository'); |
44 | $entryIds = $entryRepository->findAllEntriesIdByUserId($userId); | 44 | $entryIds = $entryRepository->findAllEntriesIdByUserId($userId); |
45 | 45 | ||
46 | $nbEntries = count($entryIds); | 46 | $nbEntries = \count($entryIds); |
47 | if (!$nbEntries) { | 47 | if (!$nbEntries) { |
48 | $io->success('No entry to reload.'); | 48 | $io->success('No entry to reload.'); |
49 | 49 | ||
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index a89bb780..b999c539 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php | |||
@@ -348,7 +348,7 @@ class ConfigController extends Controller | |||
348 | $em = $this->getDoctrine()->getManager(); | 348 | $em = $this->getDoctrine()->getManager(); |
349 | 349 | ||
350 | foreach ($tags as $tag) { | 350 | foreach ($tags as $tag) { |
351 | if (0 === count($tag->getEntries())) { | 351 | if (0 === \count($tag->getEntries())) { |
352 | $em->remove($tag); | 352 | $em->remove($tag); |
353 | } | 353 | } |
354 | } | 354 | } |
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php index 616c37f2..b6d28e59 100644 --- a/src/Wallabag/CoreBundle/Controller/TagController.php +++ b/src/Wallabag/CoreBundle/Controller/TagController.php | |||
@@ -65,7 +65,7 @@ class TagController extends Controller | |||
65 | $em->flush(); | 65 | $em->flush(); |
66 | 66 | ||
67 | // remove orphan tag in case no entries are associated to it | 67 | // remove orphan tag in case no entries are associated to it |
68 | if (0 === count($tag->getEntries())) { | 68 | if (0 === \count($tag->getEntries())) { |
69 | $em->remove($tag); | 69 | $em->remove($tag); |
70 | $em->flush(); | 70 | $em->flush(); |
71 | } | 71 | } |
diff --git a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php index 6f8c9e27..702c7f7a 100644 --- a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php +++ b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php | |||
@@ -33,7 +33,7 @@ class EntryFilterType extends AbstractType | |||
33 | 33 | ||
34 | $this->user = $tokenStorage->getToken() ? $tokenStorage->getToken()->getUser() : null; | 34 | $this->user = $tokenStorage->getToken() ? $tokenStorage->getToken()->getUser() : null; |
35 | 35 | ||
36 | if (null === $this->user || !is_object($this->user)) { | 36 | if (null === $this->user || !\is_object($this->user)) { |
37 | return; | 37 | return; |
38 | } | 38 | } |
39 | } | 39 | } |
@@ -96,7 +96,7 @@ class EntryFilterType extends AbstractType | |||
96 | ->add('domainName', TextFilterType::class, [ | 96 | ->add('domainName', TextFilterType::class, [ |
97 | 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { | 97 | 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { |
98 | $value = $values['value']; | 98 | $value = $values['value']; |
99 | if (strlen($value) <= 2 || empty($value)) { | 99 | if (\strlen($value) <= 2 || empty($value)) { |
100 | return; | 100 | return; |
101 | } | 101 | } |
102 | $expression = $filterQuery->getExpr()->like($field, $filterQuery->getExpr()->lower($filterQuery->getExpr()->literal('%' . $value . '%'))); | 102 | $expression = $filterQuery->getExpr()->like($field, $filterQuery->getExpr()->lower($filterQuery->getExpr()->literal('%' . $value . '%'))); |
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php index 2c85da62..90e00c62 100644 --- a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php +++ b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php | |||
@@ -107,7 +107,7 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder | |||
107 | */ | 107 | */ |
108 | protected function processExtraFields($extraFieldsStrings) | 108 | protected function processExtraFields($extraFieldsStrings) |
109 | { | 109 | { |
110 | if (!is_array($extraFieldsStrings)) { | 110 | if (!\is_array($extraFieldsStrings)) { |
111 | return []; | 111 | return []; |
112 | } | 112 | } |
113 | 113 | ||
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php index fe795d42..d4ea608f 100644 --- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php +++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php | |||
@@ -53,6 +53,7 @@ class ContentProxy | |||
53 | 53 | ||
54 | if ((empty($content) || false === $this->validateContent($content)) && false === $disableContentUpdate) { | 54 | if ((empty($content) || false === $this->validateContent($content)) && false === $disableContentUpdate) { |
55 | $fetchedContent = $this->graby->fetchContent($url); | 55 | $fetchedContent = $this->graby->fetchContent($url); |
56 | $fetchedContent['title'] = $this->sanitizeContentTitle($fetchedContent['title'], $fetchedContent['content_type']); | ||
56 | 57 | ||
57 | // when content is imported, we have information in $content | 58 | // when content is imported, we have information in $content |
58 | // in case fetching content goes bad, we'll keep the imported information instead of overriding them | 59 | // in case fetching content goes bad, we'll keep the imported information instead of overriding them |
@@ -85,7 +86,7 @@ class ContentProxy | |||
85 | (new LocaleConstraint()) | 86 | (new LocaleConstraint()) |
86 | ); | 87 | ); |
87 | 88 | ||
88 | if (0 === count($errors)) { | 89 | if (0 === \count($errors)) { |
89 | $entry->setLanguage($value); | 90 | $entry->setLanguage($value); |
90 | 91 | ||
91 | return; | 92 | return; |
@@ -107,7 +108,7 @@ class ContentProxy | |||
107 | (new UrlConstraint()) | 108 | (new UrlConstraint()) |
108 | ); | 109 | ); |
109 | 110 | ||
110 | if (0 === count($errors)) { | 111 | if (0 === \count($errors)) { |
111 | $entry->setPreviewPicture($value); | 112 | $entry->setPreviewPicture($value); |
112 | 113 | ||
113 | return; | 114 | return; |
@@ -177,6 +178,59 @@ class ContentProxy | |||
177 | } | 178 | } |
178 | 179 | ||
179 | /** | 180 | /** |
181 | * Try to sanitize the title of the fetched content from wrong character encodings and invalid UTF-8 character. | ||
182 | * | ||
183 | * @param $title | ||
184 | * @param $contentType | ||
185 | * | ||
186 | * @return string | ||
187 | */ | ||
188 | private function sanitizeContentTitle($title, $contentType) | ||
189 | { | ||
190 | if ('application/pdf' === $contentType) { | ||
191 | $title = $this->convertPdfEncodingToUTF8($title); | ||
192 | } | ||
193 | |||
194 | return $this->sanitizeUTF8Text($title); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * If the title from the fetched content comes from a PDF, then its very possible that the character encoding is not | ||
199 | * UTF-8. This methods tries to identify the character encoding and translate the title to UTF-8. | ||
200 | * | ||
201 | * @param $title | ||
202 | * | ||
203 | * @return string (maybe contains invalid UTF-8 character) | ||
204 | */ | ||
205 | private function convertPdfEncodingToUTF8($title) | ||
206 | { | ||
207 | // first try UTF-8 because its easier to detect its present/absence | ||
208 | foreach (['UTF-8', 'UTF-16BE', 'WINDOWS-1252'] as $encoding) { | ||
209 | if (mb_check_encoding($title, $encoding)) { | ||
210 | return mb_convert_encoding($title, 'UTF-8', $encoding); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | return $title; | ||
215 | } | ||
216 | |||
217 | /** | ||
218 | * Remove invalid UTF-8 characters from the given string. | ||
219 | * | ||
220 | * @param string $rawText | ||
221 | * | ||
222 | * @return string | ||
223 | */ | ||
224 | private function sanitizeUTF8Text($rawText) | ||
225 | { | ||
226 | if (mb_check_encoding($rawText, 'UTF-8')) { | ||
227 | return $rawText; | ||
228 | } | ||
229 | |||
230 | return iconv('UTF-8', 'UTF-8//IGNORE', $rawText); | ||
231 | } | ||
232 | |||
233 | /** | ||
180 | * Stock entry with fetched or imported content. | 234 | * Stock entry with fetched or imported content. |
181 | * Will fall back to OpenGraph data if available. | 235 | * Will fall back to OpenGraph data if available. |
182 | * | 236 | * |
@@ -212,7 +266,7 @@ class ContentProxy | |||
212 | $entry->setHttpStatus($content['status']); | 266 | $entry->setHttpStatus($content['status']); |
213 | } | 267 | } |
214 | 268 | ||
215 | if (!empty($content['authors']) && is_array($content['authors'])) { | 269 | if (!empty($content['authors']) && \is_array($content['authors'])) { |
216 | $entry->setPublishedBy($content['authors']); | 270 | $entry->setPublishedBy($content['authors']); |
217 | } | 271 | } |
218 | 272 | ||
@@ -233,7 +287,7 @@ class ContentProxy | |||
233 | } | 287 | } |
234 | 288 | ||
235 | // if content is an image, define it as a preview too | 289 | // if content is an image, define it as a preview too |
236 | if (!empty($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { | 290 | if (!empty($content['content_type']) && \in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { |
237 | $this->updatePreviewPicture($entry, $content['url']); | 291 | $this->updatePreviewPicture($entry, $content['url']); |
238 | } | 292 | } |
239 | 293 | ||
diff --git a/src/Wallabag/CoreBundle/Helper/CryptoProxy.php b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php index 7d8c9888..67d73915 100644 --- a/src/Wallabag/CoreBundle/Helper/CryptoProxy.php +++ b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php | |||
@@ -81,6 +81,6 @@ class CryptoProxy | |||
81 | */ | 81 | */ |
82 | private function mask($value) | 82 | private function mask($value) |
83 | { | 83 | { |
84 | return strlen($value) > 0 ? $value[0] . '*****' . $value[strlen($value) - 1] : 'Empty value'; | 84 | return \strlen($value) > 0 ? $value[0] . '*****' . $value[\strlen($value) - 1] : 'Empty value'; |
85 | } | 85 | } |
86 | } | 86 | } |
diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php index 487a3a23..cc3dcfce 100644 --- a/src/Wallabag/CoreBundle/Helper/DownloadImages.php +++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php | |||
@@ -198,7 +198,7 @@ class DownloadImages | |||
198 | // Must be one or more digits followed by w OR x | 198 | // Must be one or more digits followed by w OR x |
199 | $pattern = "/(?:[^\"'\s]+\s*(?:\d+[wx])+)/"; | 199 | $pattern = "/(?:[^\"'\s]+\s*(?:\d+[wx])+)/"; |
200 | preg_match_all($pattern, $srcsetAttribute, $matches); | 200 | preg_match_all($pattern, $srcsetAttribute, $matches); |
201 | $srcset = call_user_func_array('array_merge', $matches); | 201 | $srcset = \call_user_func_array('array_merge', $matches); |
202 | $srcsetUrls = array_map(function ($src) { | 202 | $srcsetUrls = array_map(function ($src) { |
203 | return trim(explode(' ', $src, 2)[0]); | 203 | return trim(explode(' ', $src, 2)[0]); |
204 | }, $srcset); | 204 | }, $srcset); |
@@ -308,7 +308,7 @@ class DownloadImages | |||
308 | $this->logger->debug('DownloadImages: Checking extension (alternative)', ['ext' => $ext]); | 308 | $this->logger->debug('DownloadImages: Checking extension (alternative)', ['ext' => $ext]); |
309 | } | 309 | } |
310 | 310 | ||
311 | if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) { | 311 | if (!\in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) { |
312 | $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping: ' . $imagePath); | 312 | $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping: ' . $imagePath); |
313 | 313 | ||
314 | return false; | 314 | return false; |
diff --git a/src/Wallabag/CoreBundle/Helper/EntriesExport.php b/src/Wallabag/CoreBundle/Helper/EntriesExport.php index 136f66f5..cbf1037b 100644 --- a/src/Wallabag/CoreBundle/Helper/EntriesExport.php +++ b/src/Wallabag/CoreBundle/Helper/EntriesExport.php | |||
@@ -45,7 +45,7 @@ class EntriesExport | |||
45 | */ | 45 | */ |
46 | public function setEntries($entries) | 46 | public function setEntries($entries) |
47 | { | 47 | { |
48 | if (!is_array($entries)) { | 48 | if (!\is_array($entries)) { |
49 | $this->language = $entries->getLanguage(); | 49 | $this->language = $entries->getLanguage(); |
50 | $entries = [$entries]; | 50 | $entries = [$entries]; |
51 | } | 51 | } |
@@ -325,7 +325,7 @@ class EntriesExport | |||
325 | { | 325 | { |
326 | $delimiter = ';'; | 326 | $delimiter = ';'; |
327 | $enclosure = '"'; | 327 | $enclosure = '"'; |
328 | $handle = fopen('php://memory', 'rb+'); | 328 | $handle = fopen('php://memory', 'b+r'); |
329 | 329 | ||
330 | fputcsv($handle, ['Title', 'URL', 'Content', 'Tags', 'MIME Type', 'Language', 'Creation date'], $delimiter, $enclosure); | 330 | fputcsv($handle, ['Title', 'URL', 'Content', 'Tags', 'MIME Type', 'Language', 'Creation date'], $delimiter, $enclosure); |
331 | 331 | ||
diff --git a/src/Wallabag/CoreBundle/Helper/PreparePagerForEntries.php b/src/Wallabag/CoreBundle/Helper/PreparePagerForEntries.php index 49c1ea41..1c2c5093 100644 --- a/src/Wallabag/CoreBundle/Helper/PreparePagerForEntries.php +++ b/src/Wallabag/CoreBundle/Helper/PreparePagerForEntries.php | |||
@@ -31,7 +31,7 @@ class PreparePagerForEntries | |||
31 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; | 31 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; |
32 | } | 32 | } |
33 | 33 | ||
34 | if (null === $user || !is_object($user)) { | 34 | if (null === $user || !\is_object($user)) { |
35 | return; | 35 | return; |
36 | } | 36 | } |
37 | 37 | ||
diff --git a/src/Wallabag/CoreBundle/Helper/Redirect.php b/src/Wallabag/CoreBundle/Helper/Redirect.php index abc84d08..9d1a6345 100644 --- a/src/Wallabag/CoreBundle/Helper/Redirect.php +++ b/src/Wallabag/CoreBundle/Helper/Redirect.php | |||
@@ -31,7 +31,7 @@ class Redirect | |||
31 | { | 31 | { |
32 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; | 32 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; |
33 | 33 | ||
34 | if (null === $user || !is_object($user)) { | 34 | if (null === $user || !\is_object($user)) { |
35 | return $url; | 35 | return $url; |
36 | } | 36 | } |
37 | 37 | ||
diff --git a/src/Wallabag/CoreBundle/Helper/TagsAssigner.php b/src/Wallabag/CoreBundle/Helper/TagsAssigner.php index 0bfe5c57..e6b4989f 100644 --- a/src/Wallabag/CoreBundle/Helper/TagsAssigner.php +++ b/src/Wallabag/CoreBundle/Helper/TagsAssigner.php | |||
@@ -32,7 +32,7 @@ class TagsAssigner | |||
32 | { | 32 | { |
33 | $tagsEntities = []; | 33 | $tagsEntities = []; |
34 | 34 | ||
35 | if (!is_array($tags)) { | 35 | if (!\is_array($tags)) { |
36 | $tags = explode(',', $tags); | 36 | $tags = explode(',', $tags); |
37 | } | 37 | } |
38 | 38 | ||
@@ -48,7 +48,7 @@ class TagsAssigner | |||
48 | $label = trim(mb_convert_case($label, MB_CASE_LOWER)); | 48 | $label = trim(mb_convert_case($label, MB_CASE_LOWER)); |
49 | 49 | ||
50 | // avoid empty tag | 50 | // avoid empty tag |
51 | if (0 === strlen($label)) { | 51 | if (0 === \strlen($label)) { |
52 | continue; | 52 | continue; |
53 | } | 53 | } |
54 | 54 | ||
diff --git a/src/Wallabag/CoreBundle/ParamConverter/UsernameRssTokenConverter.php b/src/Wallabag/CoreBundle/ParamConverter/UsernameRssTokenConverter.php index 40b5673d..4a2fcab5 100644 --- a/src/Wallabag/CoreBundle/ParamConverter/UsernameRssTokenConverter.php +++ b/src/Wallabag/CoreBundle/ParamConverter/UsernameRssTokenConverter.php | |||
@@ -36,7 +36,7 @@ class UsernameRssTokenConverter implements ParamConverterInterface | |||
36 | { | 36 | { |
37 | // If there is no manager, this means that only Doctrine DBAL is configured | 37 | // If there is no manager, this means that only Doctrine DBAL is configured |
38 | // In this case we can do nothing and just return | 38 | // In this case we can do nothing and just return |
39 | if (null === $this->registry || !count($this->registry->getManagers())) { | 39 | if (null === $this->registry || !\count($this->registry->getManagers())) { |
40 | return false; | 40 | return false; |
41 | } | 41 | } |
42 | 42 | ||
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index b5e35eff..83379998 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -21,7 +21,7 @@ class EntryRepository extends EntityRepository | |||
21 | public function getBuilderForAllByUser($userId) | 21 | public function getBuilderForAllByUser($userId) |
22 | { | 22 | { |
23 | return $this | 23 | return $this |
24 | ->getBuilderByUser($userId) | 24 | ->getSortedQueryBuilderByUser($userId) |
25 | ; | 25 | ; |
26 | } | 26 | } |
27 | 27 | ||
@@ -35,7 +35,7 @@ class EntryRepository extends EntityRepository | |||
35 | public function getBuilderForUnreadByUser($userId) | 35 | public function getBuilderForUnreadByUser($userId) |
36 | { | 36 | { |
37 | return $this | 37 | return $this |
38 | ->getBuilderByUser($userId) | 38 | ->getSortedQueryBuilderByUser($userId) |
39 | ->andWhere('e.isArchived = false') | 39 | ->andWhere('e.isArchived = false') |
40 | ; | 40 | ; |
41 | } | 41 | } |
@@ -50,7 +50,7 @@ class EntryRepository extends EntityRepository | |||
50 | public function getBuilderForArchiveByUser($userId) | 50 | public function getBuilderForArchiveByUser($userId) |
51 | { | 51 | { |
52 | return $this | 52 | return $this |
53 | ->getBuilderByUser($userId) | 53 | ->getSortedQueryBuilderByUser($userId) |
54 | ->andWhere('e.isArchived = true') | 54 | ->andWhere('e.isArchived = true') |
55 | ; | 55 | ; |
56 | } | 56 | } |
@@ -65,7 +65,7 @@ class EntryRepository extends EntityRepository | |||
65 | public function getBuilderForStarredByUser($userId) | 65 | public function getBuilderForStarredByUser($userId) |
66 | { | 66 | { |
67 | return $this | 67 | return $this |
68 | ->getBuilderByUser($userId, 'starredAt', 'desc') | 68 | ->getSortedQueryBuilderByUser($userId, 'starredAt', 'desc') |
69 | ->andWhere('e.isStarred = true') | 69 | ->andWhere('e.isStarred = true') |
70 | ; | 70 | ; |
71 | } | 71 | } |
@@ -82,7 +82,7 @@ class EntryRepository extends EntityRepository | |||
82 | public function getBuilderForSearchByUser($userId, $term, $currentRoute) | 82 | public function getBuilderForSearchByUser($userId, $term, $currentRoute) |
83 | { | 83 | { |
84 | $qb = $this | 84 | $qb = $this |
85 | ->getBuilderByUser($userId); | 85 | ->getSortedQueryBuilderByUser($userId); |
86 | 86 | ||
87 | if ('starred' === $currentRoute) { | 87 | if ('starred' === $currentRoute) { |
88 | $qb->andWhere('e.isStarred = true'); | 88 | $qb->andWhere('e.isStarred = true'); |
@@ -102,7 +102,7 @@ class EntryRepository extends EntityRepository | |||
102 | } | 102 | } |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Retrieves untagged entries for a user. | 105 | * Retrieve a sorted list of untagged entries for a user. |
106 | * | 106 | * |
107 | * @param int $userId | 107 | * @param int $userId |
108 | * | 108 | * |
@@ -111,8 +111,21 @@ class EntryRepository extends EntityRepository | |||
111 | public function getBuilderForUntaggedByUser($userId) | 111 | public function getBuilderForUntaggedByUser($userId) |
112 | { | 112 | { |
113 | return $this | 113 | return $this |
114 | ->getBuilderByUser($userId) | 114 | ->sortQueryBuilder($this->getRawBuilderForUntaggedByUser($userId)); |
115 | ->andWhere('size(e.tags) = 0'); | 115 | } |
116 | |||
117 | /** | ||
118 | * Retrieve untagged entries for a user. | ||
119 | * | ||
120 | * @param int $userId | ||
121 | * | ||
122 | * @return QueryBuilder | ||
123 | */ | ||
124 | public function getRawBuilderForUntaggedByUser($userId) | ||
125 | { | ||
126 | return $this->getQueryBuilderByUser($userId) | ||
127 | ->leftJoin('e.tags', 't') | ||
128 | ->andWhere('t.id is null'); | ||
116 | } | 129 | } |
117 | 130 | ||
118 | /** | 131 | /** |
@@ -151,7 +164,7 @@ class EntryRepository extends EntityRepository | |||
151 | $qb->andWhere('e.updatedAt > :since')->setParameter('since', new \DateTime(date('Y-m-d H:i:s', $since))); | 164 | $qb->andWhere('e.updatedAt > :since')->setParameter('since', new \DateTime(date('Y-m-d H:i:s', $since))); |
152 | } | 165 | } |
153 | 166 | ||
154 | if (is_string($tags) && '' !== $tags) { | 167 | if (\is_string($tags) && '' !== $tags) { |
155 | foreach (explode(',', $tags) as $i => $tag) { | 168 | foreach (explode(',', $tags) as $i => $tag) { |
156 | $entryAlias = 'e' . $i; | 169 | $entryAlias = 'e' . $i; |
157 | $tagAlias = 't' . $i; | 170 | $tagAlias = 't' . $i; |
@@ -260,7 +273,7 @@ class EntryRepository extends EntityRepository | |||
260 | */ | 273 | */ |
261 | public function removeTag($userId, Tag $tag) | 274 | public function removeTag($userId, Tag $tag) |
262 | { | 275 | { |
263 | $entries = $this->getBuilderByUser($userId) | 276 | $entries = $this->getSortedQueryBuilderByUser($userId) |
264 | ->innerJoin('e.tags', 't') | 277 | ->innerJoin('e.tags', 't') |
265 | ->andWhere('t.id = :tagId')->setParameter('tagId', $tag->getId()) | 278 | ->andWhere('t.id = :tagId')->setParameter('tagId', $tag->getId()) |
266 | ->getQuery() | 279 | ->getQuery() |
@@ -296,7 +309,7 @@ class EntryRepository extends EntityRepository | |||
296 | */ | 309 | */ |
297 | public function findAllByTagId($userId, $tagId) | 310 | public function findAllByTagId($userId, $tagId) |
298 | { | 311 | { |
299 | return $this->getBuilderByUser($userId) | 312 | return $this->getSortedQueryBuilderByUser($userId) |
300 | ->innerJoin('e.tags', 't') | 313 | ->innerJoin('e.tags', 't') |
301 | ->andWhere('t.id = :tagId')->setParameter('tagId', $tagId) | 314 | ->andWhere('t.id = :tagId')->setParameter('tagId', $tagId) |
302 | ->getQuery() | 315 | ->getQuery() |
@@ -320,7 +333,7 @@ class EntryRepository extends EntityRepository | |||
320 | ->getQuery() | 333 | ->getQuery() |
321 | ->getResult(); | 334 | ->getResult(); |
322 | 335 | ||
323 | if (count($res)) { | 336 | if (\count($res)) { |
324 | return current($res); | 337 | return current($res); |
325 | } | 338 | } |
326 | 339 | ||
@@ -414,7 +427,20 @@ class EntryRepository extends EntityRepository | |||
414 | } | 427 | } |
415 | 428 | ||
416 | /** | 429 | /** |
417 | * Return a query builder to used by other getBuilderFor* method. | 430 | * Return a query builder to be used by other getBuilderFor* method. |
431 | * | ||
432 | * @param int $userId | ||
433 | * | ||
434 | * @return QueryBuilder | ||
435 | */ | ||
436 | private function getQueryBuilderByUser($userId) | ||
437 | { | ||
438 | return $this->createQueryBuilder('e') | ||
439 | ->andWhere('e.user = :userId')->setParameter('userId', $userId); | ||
440 | } | ||
441 | |||
442 | /** | ||
443 | * Return a sorted query builder to be used by other getBuilderFor* method. | ||
418 | * | 444 | * |
419 | * @param int $userId | 445 | * @param int $userId |
420 | * @param string $sortBy | 446 | * @param string $sortBy |
@@ -422,10 +448,23 @@ class EntryRepository extends EntityRepository | |||
422 | * | 448 | * |
423 | * @return QueryBuilder | 449 | * @return QueryBuilder |
424 | */ | 450 | */ |
425 | private function getBuilderByUser($userId, $sortBy = 'createdAt', $direction = 'desc') | 451 | private function getSortedQueryBuilderByUser($userId, $sortBy = 'createdAt', $direction = 'desc') |
426 | { | 452 | { |
427 | return $this->createQueryBuilder('e') | 453 | return $this->sortQueryBuilder($this->getQueryBuilderByUser($userId), $sortBy, $direction); |
428 | ->andWhere('e.user = :userId')->setParameter('userId', $userId) | 454 | } |
455 | |||
456 | /** | ||
457 | * Return the given QueryBuilder with an orderBy() call. | ||
458 | * | ||
459 | * @param QueryBuilder $qb | ||
460 | * @param string $sortBy | ||
461 | * @param string $direction | ||
462 | * | ||
463 | * @return QueryBuilder | ||
464 | */ | ||
465 | private function sortQueryBuilder(QueryBuilder $qb, $sortBy = 'createdAt', $direction = 'desc') | ||
466 | { | ||
467 | return $qb | ||
429 | ->orderBy(sprintf('e.%s', $sortBy), $direction); | 468 | ->orderBy(sprintf('e.%s', $sortBy), $direction); |
430 | } | 469 | } |
431 | } | 470 | } |
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php index 5c45211f..3ae9d414 100644 --- a/src/Wallabag/CoreBundle/Repository/TagRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php | |||
@@ -30,7 +30,7 @@ class TagRepository extends EntityRepository | |||
30 | $query->setResultCacheLifetime($cacheLifeTime); | 30 | $query->setResultCacheLifetime($cacheLifeTime); |
31 | } | 31 | } |
32 | 32 | ||
33 | return count($query->getArrayResult()); | 33 | return \count($query->getArrayResult()); |
34 | } | 34 | } |
35 | 35 | ||
36 | /** | 36 | /** |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_no_preview.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_no_preview.html.twig index 8e6bbae0..4fd4debd 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_no_preview.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_no_preview.html.twig | |||
@@ -1,5 +1,12 @@ | |||
1 | <div class="card"> | 1 | <div class="card"> |
2 | <div class="card-body"> | 2 | <div class="card-body"> |
3 | <div class="card-image waves-effect waves-block waves-light"> | ||
4 | <ul class="card-entry-labels"> | ||
5 | {% for tag in entry.tags | slice(0, 3) %} | ||
6 | <li><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a></li> | ||
7 | {% endfor %} | ||
8 | </ul> | ||
9 | </div> | ||
3 | {% include "@WallabagCore/themes/material/Entry/Card/_content.html.twig" with {'entry': entry} only %} | 10 | {% include "@WallabagCore/themes/material/Entry/Card/_content.html.twig" with {'entry': entry} only %} |
4 | </div> | 11 | </div> |
5 | 12 | ||
diff --git a/src/Wallabag/CoreBundle/Tools/Utils.php b/src/Wallabag/CoreBundle/Tools/Utils.php index eba21c02..46bb1dc5 100644 --- a/src/Wallabag/CoreBundle/Tools/Utils.php +++ b/src/Wallabag/CoreBundle/Tools/Utils.php | |||
@@ -29,6 +29,6 @@ class Utils | |||
29 | */ | 29 | */ |
30 | public static function getReadingTime($text) | 30 | public static function getReadingTime($text) |
31 | { | 31 | { |
32 | return floor(count(preg_split('~[^\p{L}\p{N}\']+~u', strip_tags($text))) / 200); | 32 | return floor(\count(preg_split('~[^\p{L}\p{N}\']+~u', strip_tags($text))) / 200); |
33 | } | 33 | } |
34 | } | 34 | } |
diff --git a/src/Wallabag/CoreBundle/Twig/WallabagExtension.php b/src/Wallabag/CoreBundle/Twig/WallabagExtension.php index 8992117e..00b1e595 100644 --- a/src/Wallabag/CoreBundle/Twig/WallabagExtension.php +++ b/src/Wallabag/CoreBundle/Twig/WallabagExtension.php | |||
@@ -64,7 +64,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa | |||
64 | { | 64 | { |
65 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; | 65 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; |
66 | 66 | ||
67 | if (null === $user || !is_object($user)) { | 67 | if (null === $user || !\is_object($user)) { |
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
@@ -96,7 +96,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa | |||
96 | $query->useResultCache(true); | 96 | $query->useResultCache(true); |
97 | $query->setResultCacheLifetime($this->lifeTime); | 97 | $query->setResultCacheLifetime($this->lifeTime); |
98 | 98 | ||
99 | return count($query->getArrayResult()); | 99 | return \count($query->getArrayResult()); |
100 | } | 100 | } |
101 | 101 | ||
102 | /** | 102 | /** |
@@ -108,7 +108,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa | |||
108 | { | 108 | { |
109 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; | 109 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; |
110 | 110 | ||
111 | if (null === $user || !is_object($user)) { | 111 | if (null === $user || !\is_object($user)) { |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
@@ -124,7 +124,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa | |||
124 | { | 124 | { |
125 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; | 125 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; |
126 | 126 | ||
127 | if (null === $user || !is_object($user)) { | 127 | if (null === $user || !\is_object($user)) { |
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
130 | 130 | ||
@@ -137,7 +137,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa | |||
137 | $query->useResultCache(true); | 137 | $query->useResultCache(true); |
138 | $query->setResultCacheLifetime($this->lifeTime); | 138 | $query->setResultCacheLifetime($this->lifeTime); |
139 | 139 | ||
140 | $nbArchives = count($query->getArrayResult()); | 140 | $nbArchives = \count($query->getArrayResult()); |
141 | 141 | ||
142 | $interval = $user->getCreatedAt()->diff(new \DateTime('now')); | 142 | $interval = $user->getCreatedAt()->diff(new \DateTime('now')); |
143 | $nbDays = (int) $interval->format('%a') ?: 1; | 143 | $nbDays = (int) $interval->format('%a') ?: 1; |