]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #3706 from shtrom/fix/gnu-make-bash
authorKevin Decherf <kevin@kdecherf.com>
Sun, 14 Oct 2018 18:07:42 +0000 (20:07 +0200)
committerGitHub <noreply@github.com>
Sun, 14 Oct 2018 18:07:42 +0000 (20:07 +0200)
Makefile fixes for non GNU systems

60 files changed:
.scrutinizer.yml
.travis.yml
app/DoctrineMigrations/Version20170719231144.php
docker/php/Dockerfile
package.json
scripts/release.sh
src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php
src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php
src/Wallabag/ApiBundle/Controller/EntryRestController.php
src/Wallabag/ApiBundle/Controller/TagRestController.php
src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php
src/Wallabag/CoreBundle/Command/ExportCommand.php
src/Wallabag/CoreBundle/Command/InstallCommand.php
src/Wallabag/CoreBundle/Command/ListUserCommand.php
src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php
src/Wallabag/CoreBundle/Controller/ConfigController.php
src/Wallabag/CoreBundle/Controller/TagController.php
src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
src/Wallabag/CoreBundle/Helper/ContentProxy.php
src/Wallabag/CoreBundle/Helper/CryptoProxy.php
src/Wallabag/CoreBundle/Helper/DownloadImages.php
src/Wallabag/CoreBundle/Helper/EntriesExport.php
src/Wallabag/CoreBundle/Helper/PreparePagerForEntries.php
src/Wallabag/CoreBundle/Helper/Redirect.php
src/Wallabag/CoreBundle/Helper/TagsAssigner.php
src/Wallabag/CoreBundle/ParamConverter/UsernameRssTokenConverter.php
src/Wallabag/CoreBundle/Repository/EntryRepository.php
src/Wallabag/CoreBundle/Repository/TagRepository.php
src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_no_preview.html.twig
src/Wallabag/CoreBundle/Tools/Utils.php
src/Wallabag/CoreBundle/Twig/WallabagExtension.php
src/Wallabag/ImportBundle/Command/ImportCommand.php
src/Wallabag/ImportBundle/Controller/BrowserController.php
src/Wallabag/ImportBundle/Controller/InstapaperController.php
src/Wallabag/ImportBundle/Controller/PinboardController.php
src/Wallabag/ImportBundle/Controller/ReadabilityController.php
src/Wallabag/ImportBundle/Controller/WallabagController.php
src/Wallabag/ImportBundle/Import/BrowserImport.php
src/Wallabag/ImportBundle/Import/InstapaperImport.php
src/Wallabag/ImportBundle/Import/PocketImport.php
src/Wallabag/ImportBundle/Import/WallabagV1Import.php
tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php
tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php
tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php
tests/Wallabag/CoreBundle/Controller/TagControllerTest.php
tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php
tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php
tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php
tests/Wallabag/ImportBundle/Controller/InstapaperControllerTest.php
tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php
tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php
tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php
tests/Wallabag/ImportBundle/Controller/WallabagV2ControllerTest.php
tests/Wallabag/ImportBundle/fixtures/instapaper-export.csv
tests/Wallabag/ImportBundle/fixtures/wallabag-v2.json
tests/Wallabag/UserBundle/Mailer/AuthCodeMailerTest.php
var/SymfonyRequirements.php
yarn.lock

index dee92922afd2b5d672789943e8e44439cdfefe6a..194297f672c4e4aacdc98da01d916d3076a50152 100644 (file)
@@ -26,3 +26,18 @@ tools:
 checks:
     php:
         code_rating: true
+
+# use the new PHP analysis engine
+# https://scrutinizer-ci.com/docs/tools/php/php-analyzer/guides/migrate_to_new_php_analysis
+build:
+    nodes:
+        analysis:
+            tests:
+                override:
+                    - php-scrutinizer-run
+
+    dependencies:
+        override:
+            - npm install -g 'yarn'
+            - yarn install --force
+            - COMPOSER_MEMORY_LIMIT=-1 composer install -o --no-interaction --no-progress --prefer-dist
index c6c03dc3fce35b70ed498f93b7e0a1127f9693ad..eb40953367e45d7a8d367132e214c5e44dc8fec3 100644 (file)
@@ -44,7 +44,6 @@ matrix:
         - php: 7.0
           env: CS_FIXER=run VALIDATE_TRANSLATION_FILE=run ASSETS=build DB=sqlite
     allow_failures:
-        - php: 7.2
         - php: nightly
 
 # exclude v1 branches
index 04358c7ceb40749ad86eafc2e33711048187572f..93fe7f26031c44fe426f51ff78601fbc9776b6eb 100644 (file)
@@ -55,7 +55,7 @@ class Version20170719231144 extends WallabagMigration
             }
 
             // Just in case...
-            if (count($ids) > 0) {
+            if (\count($ids) > 0) {
                 // Merge tags
                 $this->addSql('
                     UPDATE ' . $this->getTable('entry_tag') . '
index 1fb1f29826e7c402cecb9274006767dea4dd4558..d0266ec74496274b7a4fd2c0c780659361982e1c 100644 (file)
@@ -4,10 +4,10 @@ FROM php:fpm
 ARG timezone='Europe/Paris'
 
 RUN apt-get update && apt-get install -y \
-        libmcrypt-dev libicu-dev libpq-dev libxml2-dev libpng12-dev libjpeg-dev \
+        libmcrypt-dev libicu-dev libpq-dev libxml2-dev libpng-dev libjpeg-dev \
     && /usr/local/bin/docker-php-ext-configure gd --with-jpeg-dir=/usr/include \
     && docker-php-ext-install \
-        iconv mcrypt mbstring intl pdo pdo_mysql pdo_pgsql gd
+        iconv mbstring intl pdo pdo_mysql pdo_pgsql gd
 
 RUN echo "date.timezone="$timezone > /usr/local/etc/php/conf.d/date_timezone.ini
 
index 8d856bbb2803154f22bfbd64e8c610b1a4c4ed0d..ac894e7978e7434e5b4ade38b881d07448e27c9c 100644 (file)
@@ -1,13 +1,13 @@
 {
   "name": "wallabag",
-  "version": "2.2.2",
+  "version": "2.3.3",
   "description": "wallabag is a self hostable application for saving web pages",
   "private": true,
   "directories": {
     "doc": "docs"
   },
   "engines": {
-    "node": ">4.8"
+    "node": ">=6.10"
   },
   "repository": {
     "type": "git",
index bfb65684c95949b18877dd7c38f0a24d97200ae2..6186a48663e2f9ea324997390a7426072be5b95f 100755 (executable)
@@ -1,6 +1,6 @@
 #! /usr/bin/env bash
 # You can execute this file to create a new package for wallabag
-# eg: `sh release.sh master /tmp wllbg-release prod`
+# eg: `sh release.sh 2.3.3 /tmp wllbg-release prod`
 
 VERSION=$1
 TMP_FOLDER=$2
@@ -10,11 +10,11 @@ ENV=$4
 rm -rf $TMP_FOLDER/$RELEASE_FOLDER
 mkdir $TMP_FOLDER/$RELEASE_FOLDER
 git clone git@github.com:wallabag/wallabag.git -b $VERSION $TMP_FOLDER/$RELEASE_FOLDER/$VERSION
-cd $TMP_FOLDER/$RELEASE_FOLDER/$VERSION && SYMFONY_ENV=$ENV composer up -n --no-dev
+cd $TMP_FOLDER/$RELEASE_FOLDER/$VERSION && SYMFONY_ENV=$ENV COMPOSER_MEMORY_LIMIT=-1 composer up -n --no-dev
 cd $TMP_FOLDER/$RELEASE_FOLDER/$VERSION && php bin/console wallabag:install --env=$ENV
 cd $TMP_FOLDER/$RELEASE_FOLDER/$VERSION && php bin/console assets:install --env=$ENV --symlink --relative
 cd $TMP_FOLDER/$RELEASE_FOLDER && tar czf wallabag-$VERSION.tar.gz --exclude="var/cache/*" --exclude="var/logs/*" --exclude="var/sessions/*" --exclude=".git" $VERSION
 echo "MD5 checksum of the package for wallabag $VERSION"
 md5 $TMP_FOLDER/$RELEASE_FOLDER/wallabag-$VERSION.tar.gz
-scp $TMP_FOLDER/$RELEASE_FOLDER/wallabag-$VERSION.tar.gz framasoft_bag@78.46.248.87:/var/www/framabag.org/web
-rm -rf $TMP_FOLDER/$RELEASE_FOLDER
+echo "Package to upload to the release server:"
+echo $TMP_FOLDER/$RELEASE_FOLDER/wallabag-$VERSION.tar.gz
index f3090e6503a38a6c562ab4648a4f315365b67454..3a7421c74ddc6fcf7225b2ef98d828a7e445ff5d 100644 (file)
@@ -28,7 +28,7 @@ class WallabagAnnotationController extends FOSRestController
             ->getDoctrine()
             ->getRepository('WallabagAnnotationBundle:Annotation')
             ->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId());
-        $total = count($annotationRows);
+        $total = \count($annotationRows);
         $annotations = ['total' => $total, 'rows' => $annotationRows];
 
         $json = $this->get('jms_serializer')->serialize($annotations, 'json');
index b44f7e647acc4d35a5d0af70a63fd0bc48785680..0de5c934e8d53f25df111d329f829446bf8e02cb 100644 (file)
@@ -21,7 +21,7 @@ class AnnotationRepository extends EntityRepository
     public function getBuilderForAllByUser($userId)
     {
         return $this
-            ->getBuilderByUser($userId)
+            ->getSortedQueryBuilderByUser($userId)
         ;
     }
 
@@ -133,7 +133,7 @@ class AnnotationRepository extends EntityRepository
      *
      * @return QueryBuilder
      */
-    private function getBuilderByUser($userId)
+    private function getSortedQueryBuilderByUser($userId)
     {
         return $this->createQueryBuilder('a')
             ->leftJoin('a.user', 'u')
index fc47c479ff4bc0df926c2acde344e239eb0e7366..0b4e74a0f1d69d332d710300d2471a69132a6d24 100644 (file)
@@ -102,7 +102,7 @@ class EntryRestController extends WallabagRestController
         $order = $request->query->get('order', 'desc');
         $page = (int) $request->query->get('page', 1);
         $perPage = (int) $request->query->get('perPage', 30);
-        $tags = is_array($request->query->get('tags')) ? '' : (string) $request->query->get('tags', '');
+        $tags = \is_array($request->query->get('tags')) ? '' : (string) $request->query->get('tags', '');
         $since = $request->query->get('since', 0);
 
         /** @var \Pagerfanta\Pagerfanta $pager */
@@ -253,7 +253,7 @@ class EntryRestController extends WallabagRestController
 
         $limit = $this->container->getParameter('wallabag_core.api_limit_mass_actions');
 
-        if (count($urls) > $limit) {
+        if (\count($urls) > $limit) {
             throw new HttpException(400, 'API limit reached');
         }
 
@@ -347,7 +347,7 @@ class EntryRestController extends WallabagRestController
                     'open_graph' => [
                         'og_image' => !empty($data['picture']) ? $data['picture'] : $entry->getPreviewPicture(),
                     ],
-                    'authors' => is_string($data['authors']) ? explode(',', $data['authors']) : $entry->getPublishedBy(),
+                    'authors' => \is_string($data['authors']) ? explode(',', $data['authors']) : $entry->getPublishedBy(),
                 ]
             );
         } catch (\Exception $e) {
@@ -461,7 +461,7 @@ class EntryRestController extends WallabagRestController
             $contentProxy->updateLanguage($entry, $data['language']);
         }
 
-        if (!empty($data['authors']) && is_string($data['authors'])) {
+        if (!empty($data['authors']) && \is_string($data['authors'])) {
             $entry->setPublishedBy(explode(',', $data['authors']));
         }
 
index 9d333fe4ee4f3792f1a71ea361acfbfc06e1caaf..c6d6df6a91423718f5006cbace9f569eca6e7a7c 100644 (file)
@@ -138,14 +138,14 @@ class TagRestController extends WallabagRestController
      */
     private function cleanOrphanTag($tags)
     {
-        if (!is_array($tags)) {
+        if (!\is_array($tags)) {
             $tags = [$tags];
         }
 
         $em = $this->getDoctrine()->getManager();
 
         foreach ($tags as $tag) {
-            if (0 === count($tag->getEntries())) {
+            if (0 === \count($tag->getEntries())) {
                 $em->remove($tag);
             }
         }
index b58909db9f9c40b8c6cadbbdf25f27d7a8240a86..99170967018af889b1cf1e13d5beb5cb110308c5 100644 (file)
@@ -51,7 +51,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
         } else {
             $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll();
 
-            $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', count($users)));
+            $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', \count($users)));
 
             foreach ($users as $user) {
                 $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername()));
@@ -79,7 +79,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
             $url = $this->similarUrl($entry['url']);
 
             /* @var $entry Entry */
-            if (in_array($url, $urls, true)) {
+            if (\in_array($url, $urls, true)) {
                 ++$duplicatesCount;
 
                 $em->remove($repo->find($entry['id']));
@@ -96,8 +96,8 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
 
     private function similarUrl($url)
     {
-        if (in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls
-            return substr($url, 0, strlen($url));
+        if (\in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls
+            return substr($url, 0, \strlen($url));
         }
 
         return $url;
index 75e9ad91bc0c4d117810e96c113c7dcb11e8a7b6..128f9d65bc7949c758b0305725b38bff0d5df43b 100644 (file)
@@ -47,7 +47,7 @@ class ExportCommand extends ContainerAwareCommand
             ->getQuery()
             ->getResult();
 
-        $io->text(sprintf('Exporting <info>%d</info> entrie(s) for user <info>%s</info>...', count($entries), $user->getUserName()));
+        $io->text(sprintf('Exporting <info>%d</info> entrie(s) for user <info>%s</info>...', \count($entries), $user->getUserName()));
 
         $filePath = $input->getArgument('filepath');
 
index a56a32575671d4ae350fea82a05403f648fdb2ef..3c76545cd37c8411e6223ade425fe93ff965ae6e 100644 (file)
@@ -81,7 +81,7 @@ class InstallCommand extends ContainerAwareCommand
         $status = '<info>OK!</info>';
         $help = '';
 
-        if (!extension_loaded($this->getContainer()->getParameter('database_driver'))) {
+        if (!\extension_loaded($this->getContainer()->getParameter('database_driver'))) {
             $fulfilled = false;
             $status = '<error>ERROR!</error>';
             $help = 'Database driver "' . $this->getContainer()->getParameter('database_driver') . '" is not installed.';
@@ -146,7 +146,7 @@ class InstallCommand extends ContainerAwareCommand
             $status = '<info>OK!</info>';
             $help = '';
 
-            if (!function_exists($functionRequired)) {
+            if (!\function_exists($functionRequired)) {
                 $fulfilled = false;
                 $status = '<error>ERROR!</error>';
                 $help = 'You need the ' . $functionRequired . ' function activated';
@@ -371,7 +371,7 @@ class InstallCommand extends ContainerAwareCommand
         }
 
         try {
-            return in_array($databaseName, $schemaManager->listDatabases(), true);
+            return \in_array($databaseName, $schemaManager->listDatabases(), true);
         } catch (\Doctrine\DBAL\Exception\DriverException $e) {
             // it means we weren't able to get database list, assume the database doesn't exist
 
@@ -389,6 +389,6 @@ class InstallCommand extends ContainerAwareCommand
     {
         $schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager();
 
-        return count($schemaManager->listTableNames()) > 0 ? true : false;
+        return \count($schemaManager->listTableNames()) > 0 ? true : false;
     }
 }
index 68e515da2c5686a95ab0ef7e5a182816c8943ed9..a7101a02021e4d9526b792a086befc3582f37168 100644 (file)
@@ -50,7 +50,7 @@ class ListUserCommand extends ContainerAwareCommand
         $io->success(
             sprintf(
                 '%s/%s%s user(s) displayed.',
-                count($users),
+                \count($users),
                 $nbUsers,
                 null === $input->getArgument('search') ? '' : ' (filtered)'
             )
index 91998841cce246523ce672fe23d0d41a639637e0..10918872f9cc0ed5480bccb9a8eb0a337a0162fe 100644 (file)
@@ -43,7 +43,7 @@ class ReloadEntryCommand extends ContainerAwareCommand
         $entryRepository = $this->getContainer()->get('wallabag_core.entry_repository');
         $entryIds = $entryRepository->findAllEntriesIdByUserId($userId);
 
-        $nbEntries = count($entryIds);
+        $nbEntries = \count($entryIds);
         if (!$nbEntries) {
             $io->success('No entry to reload.');
 
index a89bb7805b6bc98c9129620eaaa8ff4016c65efb..b999c539f1aa32a7c387cc0b9b80dbc35c7ad91e 100644 (file)
@@ -348,7 +348,7 @@ class ConfigController extends Controller
         $em = $this->getDoctrine()->getManager();
 
         foreach ($tags as $tag) {
-            if (0 === count($tag->getEntries())) {
+            if (0 === \count($tag->getEntries())) {
                 $em->remove($tag);
             }
         }
index 616c37f2c63e23fdb9a407aec3f294bd67d57207..b6d28e59d63c73a2fb925f63ebacb72f18d69ed2 100644 (file)
@@ -65,7 +65,7 @@ class TagController extends Controller
         $em->flush();
 
         // remove orphan tag in case no entries are associated to it
-        if (0 === count($tag->getEntries())) {
+        if (0 === \count($tag->getEntries())) {
             $em->remove($tag);
             $em->flush();
         }
index 6f8c9e27137c953a4170943cd6b7c43a5a0b6166..702c7f7aa03d196939d8f51cd747b803794e34fa 100644 (file)
@@ -33,7 +33,7 @@ class EntryFilterType extends AbstractType
 
         $this->user = $tokenStorage->getToken() ? $tokenStorage->getToken()->getUser() : null;
 
-        if (null === $this->user || !is_object($this->user)) {
+        if (null === $this->user || !\is_object($this->user)) {
             return;
         }
     }
@@ -96,7 +96,7 @@ class EntryFilterType extends AbstractType
             ->add('domainName', TextFilterType::class, [
                 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
                     $value = $values['value'];
-                    if (strlen($value) <= 2 || empty($value)) {
+                    if (\strlen($value) <= 2 || empty($value)) {
                         return;
                     }
                     $expression = $filterQuery->getExpr()->like($field, $filterQuery->getExpr()->lower($filterQuery->getExpr()->literal('%' . $value . '%')));
index 2c85da6259d0141a5b0e06fe5bd6c441e77efaa4..90e00c62d9aaeff353e5f356ec6fcc4703e9d5db 100644 (file)
@@ -107,7 +107,7 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
      */
     protected function processExtraFields($extraFieldsStrings)
     {
-        if (!is_array($extraFieldsStrings)) {
+        if (!\is_array($extraFieldsStrings)) {
             return [];
         }
 
index fe795d42b5669c967368d685cc334dd0a193e52f..d4ea608f3c724d6ae9f896199fb23ede3fc96435 100644 (file)
@@ -53,6 +53,7 @@ class ContentProxy
 
         if ((empty($content) || false === $this->validateContent($content)) && false === $disableContentUpdate) {
             $fetchedContent = $this->graby->fetchContent($url);
+            $fetchedContent['title'] = $this->sanitizeContentTitle($fetchedContent['title'], $fetchedContent['content_type']);
 
             // when content is imported, we have information in $content
             // in case fetching content goes bad, we'll keep the imported information instead of overriding them
@@ -85,7 +86,7 @@ class ContentProxy
             (new LocaleConstraint())
         );
 
-        if (0 === count($errors)) {
+        if (0 === \count($errors)) {
             $entry->setLanguage($value);
 
             return;
@@ -107,7 +108,7 @@ class ContentProxy
             (new UrlConstraint())
         );
 
-        if (0 === count($errors)) {
+        if (0 === \count($errors)) {
             $entry->setPreviewPicture($value);
 
             return;
@@ -176,6 +177,59 @@ class ContentProxy
         $entry->setTitle($path);
     }
 
+    /**
+     * Try to sanitize the title of the fetched content from wrong character encodings and invalid UTF-8 character.
+     *
+     * @param $title
+     * @param $contentType
+     *
+     * @return string
+     */
+    private function sanitizeContentTitle($title, $contentType)
+    {
+        if ('application/pdf' === $contentType) {
+            $title = $this->convertPdfEncodingToUTF8($title);
+        }
+
+        return $this->sanitizeUTF8Text($title);
+    }
+
+    /**
+     * If the title from the fetched content comes from a PDF, then its very possible that the character encoding is not
+     * UTF-8. This methods tries to identify the character encoding and translate the title to UTF-8.
+     *
+     * @param $title
+     *
+     * @return string (maybe contains invalid UTF-8 character)
+     */
+    private function convertPdfEncodingToUTF8($title)
+    {
+        // first try UTF-8 because its easier to detect its present/absence
+        foreach (['UTF-8', 'UTF-16BE', 'WINDOWS-1252'] as $encoding) {
+            if (mb_check_encoding($title, $encoding)) {
+                return mb_convert_encoding($title, 'UTF-8', $encoding);
+            }
+        }
+
+        return $title;
+    }
+
+    /**
+     * Remove invalid UTF-8 characters from the given string.
+     *
+     * @param string $rawText
+     *
+     * @return string
+     */
+    private function sanitizeUTF8Text($rawText)
+    {
+        if (mb_check_encoding($rawText, 'UTF-8')) {
+            return $rawText;
+        }
+
+        return iconv('UTF-8', 'UTF-8//IGNORE', $rawText);
+    }
+
     /**
      * Stock entry with fetched or imported content.
      * Will fall back to OpenGraph data if available.
@@ -212,7 +266,7 @@ class ContentProxy
             $entry->setHttpStatus($content['status']);
         }
 
-        if (!empty($content['authors']) && is_array($content['authors'])) {
+        if (!empty($content['authors']) && \is_array($content['authors'])) {
             $entry->setPublishedBy($content['authors']);
         }
 
@@ -233,7 +287,7 @@ class ContentProxy
         }
 
         // if content is an image, define it as a preview too
-        if (!empty($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) {
+        if (!empty($content['content_type']) && \in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) {
             $this->updatePreviewPicture($entry, $content['url']);
         }
 
index 7d8c9888800d445be8ccf891bf57f780a04d3c3d..67d739156439dd27e431f3112b5efd40178093c0 100644 (file)
@@ -81,6 +81,6 @@ class CryptoProxy
      */
     private function mask($value)
     {
-        return strlen($value) > 0 ? $value[0] . '*****' . $value[strlen($value) - 1] : 'Empty value';
+        return \strlen($value) > 0 ? $value[0] . '*****' . $value[\strlen($value) - 1] : 'Empty value';
     }
 }
index 487a3a238eff43ff4316f1897f9fb65deb5310e2..cc3dcfceb7796ffcb457e749eb654680347f3dc8 100644 (file)
@@ -198,7 +198,7 @@ class DownloadImages
                 // Must be one or more digits followed by w OR x
                 $pattern = "/(?:[^\"'\s]+\s*(?:\d+[wx])+)/";
                 preg_match_all($pattern, $srcsetAttribute, $matches);
-                $srcset = call_user_func_array('array_merge', $matches);
+                $srcset = \call_user_func_array('array_merge', $matches);
                 $srcsetUrls = array_map(function ($src) {
                     return trim(explode(' ', $src, 2)[0]);
                 }, $srcset);
@@ -308,7 +308,7 @@ class DownloadImages
             $this->logger->debug('DownloadImages: Checking extension (alternative)', ['ext' => $ext]);
         }
 
-        if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) {
+        if (!\in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) {
             $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping: ' . $imagePath);
 
             return false;
index 136f66f5292b012698593ec98ecf63c799f0d1cb..cbf1037bff60d53715be00325f0da4fa15e0f918 100644 (file)
@@ -45,7 +45,7 @@ class EntriesExport
      */
     public function setEntries($entries)
     {
-        if (!is_array($entries)) {
+        if (!\is_array($entries)) {
             $this->language = $entries->getLanguage();
             $entries = [$entries];
         }
@@ -325,7 +325,7 @@ class EntriesExport
     {
         $delimiter = ';';
         $enclosure = '"';
-        $handle = fopen('php://memory', 'rb+');
+        $handle = fopen('php://memory', 'b+r');
 
         fputcsv($handle, ['Title', 'URL', 'Content', 'Tags', 'MIME Type', 'Language', 'Creation date'], $delimiter, $enclosure);
 
index 49c1ea4142aa6bd496eac9aeb6042ab1008d415b..1c2c509316bd49fafb2d8eb7ed608c3c13182033 100644 (file)
@@ -31,7 +31,7 @@ class PreparePagerForEntries
             $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
         }
 
-        if (null === $user || !is_object($user)) {
+        if (null === $user || !\is_object($user)) {
             return;
         }
 
index abc84d089822ab6bf6f8c425f5df6acecddfbe53..9d1a6345d37dca0ca1509fe57761c3e8c64da26b 100644 (file)
@@ -31,7 +31,7 @@ class Redirect
     {
         $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
 
-        if (null === $user || !is_object($user)) {
+        if (null === $user || !\is_object($user)) {
             return $url;
         }
 
index 0bfe5c572a5e1d72d338433ad81630c596755114..e6b4989f8d64ba638b30e6bd7554bb96d8aa799e 100644 (file)
@@ -32,7 +32,7 @@ class TagsAssigner
     {
         $tagsEntities = [];
 
-        if (!is_array($tags)) {
+        if (!\is_array($tags)) {
             $tags = explode(',', $tags);
         }
 
@@ -48,7 +48,7 @@ class TagsAssigner
             $label = trim(mb_convert_case($label, MB_CASE_LOWER));
 
             // avoid empty tag
-            if (0 === strlen($label)) {
+            if (0 === \strlen($label)) {
                 continue;
             }
 
index 40b5673ddf62310d61b9484a148b71bf1bb55281..4a2fcab5ffc9428b35d7fd8a0d55188d29a00007 100644 (file)
@@ -36,7 +36,7 @@ class UsernameRssTokenConverter implements ParamConverterInterface
     {
         // If there is no manager, this means that only Doctrine DBAL is configured
         // In this case we can do nothing and just return
-        if (null === $this->registry || !count($this->registry->getManagers())) {
+        if (null === $this->registry || !\count($this->registry->getManagers())) {
             return false;
         }
 
index b5e35eff3848a69a8e0ee43e769a7fa55aee18b1..83379998d203bdc2896195da2ab30fe3a4c79004 100644 (file)
@@ -21,7 +21,7 @@ class EntryRepository extends EntityRepository
     public function getBuilderForAllByUser($userId)
     {
         return $this
-            ->getBuilderByUser($userId)
+            ->getSortedQueryBuilderByUser($userId)
         ;
     }
 
@@ -35,7 +35,7 @@ class EntryRepository extends EntityRepository
     public function getBuilderForUnreadByUser($userId)
     {
         return $this
-            ->getBuilderByUser($userId)
+            ->getSortedQueryBuilderByUser($userId)
             ->andWhere('e.isArchived = false')
         ;
     }
@@ -50,7 +50,7 @@ class EntryRepository extends EntityRepository
     public function getBuilderForArchiveByUser($userId)
     {
         return $this
-            ->getBuilderByUser($userId)
+            ->getSortedQueryBuilderByUser($userId)
             ->andWhere('e.isArchived = true')
         ;
     }
@@ -65,7 +65,7 @@ class EntryRepository extends EntityRepository
     public function getBuilderForStarredByUser($userId)
     {
         return $this
-            ->getBuilderByUser($userId, 'starredAt', 'desc')
+            ->getSortedQueryBuilderByUser($userId, 'starredAt', 'desc')
             ->andWhere('e.isStarred = true')
         ;
     }
@@ -82,7 +82,7 @@ class EntryRepository extends EntityRepository
     public function getBuilderForSearchByUser($userId, $term, $currentRoute)
     {
         $qb = $this
-            ->getBuilderByUser($userId);
+            ->getSortedQueryBuilderByUser($userId);
 
         if ('starred' === $currentRoute) {
             $qb->andWhere('e.isStarred = true');
@@ -102,7 +102,7 @@ class EntryRepository extends EntityRepository
     }
 
     /**
-     * Retrieves untagged entries for a user.
+     * Retrieve a sorted list of untagged entries for a user.
      *
      * @param int $userId
      *
@@ -111,8 +111,21 @@ class EntryRepository extends EntityRepository
     public function getBuilderForUntaggedByUser($userId)
     {
         return $this
-            ->getBuilderByUser($userId)
-            ->andWhere('size(e.tags) = 0');
+            ->sortQueryBuilder($this->getRawBuilderForUntaggedByUser($userId));
+    }
+
+    /**
+     * Retrieve untagged entries for a user.
+     *
+     * @param int $userId
+     *
+     * @return QueryBuilder
+     */
+    public function getRawBuilderForUntaggedByUser($userId)
+    {
+        return $this->getQueryBuilderByUser($userId)
+            ->leftJoin('e.tags', 't')
+            ->andWhere('t.id is null');
     }
 
     /**
@@ -151,7 +164,7 @@ class EntryRepository extends EntityRepository
             $qb->andWhere('e.updatedAt > :since')->setParameter('since', new \DateTime(date('Y-m-d H:i:s', $since)));
         }
 
-        if (is_string($tags) && '' !== $tags) {
+        if (\is_string($tags) && '' !== $tags) {
             foreach (explode(',', $tags) as $i => $tag) {
                 $entryAlias = 'e' . $i;
                 $tagAlias = 't' . $i;
@@ -260,7 +273,7 @@ class EntryRepository extends EntityRepository
      */
     public function removeTag($userId, Tag $tag)
     {
-        $entries = $this->getBuilderByUser($userId)
+        $entries = $this->getSortedQueryBuilderByUser($userId)
             ->innerJoin('e.tags', 't')
             ->andWhere('t.id = :tagId')->setParameter('tagId', $tag->getId())
             ->getQuery()
@@ -296,7 +309,7 @@ class EntryRepository extends EntityRepository
      */
     public function findAllByTagId($userId, $tagId)
     {
-        return $this->getBuilderByUser($userId)
+        return $this->getSortedQueryBuilderByUser($userId)
             ->innerJoin('e.tags', 't')
             ->andWhere('t.id = :tagId')->setParameter('tagId', $tagId)
             ->getQuery()
@@ -320,7 +333,7 @@ class EntryRepository extends EntityRepository
             ->getQuery()
             ->getResult();
 
-        if (count($res)) {
+        if (\count($res)) {
             return current($res);
         }
 
@@ -414,7 +427,20 @@ class EntryRepository extends EntityRepository
     }
 
     /**
-     * Return a query builder to used by other getBuilderFor* method.
+     * Return a query builder to be used by other getBuilderFor* method.
+     *
+     * @param int $userId
+     *
+     * @return QueryBuilder
+     */
+    private function getQueryBuilderByUser($userId)
+    {
+        return $this->createQueryBuilder('e')
+            ->andWhere('e.user = :userId')->setParameter('userId', $userId);
+    }
+
+    /**
+     * Return a sorted query builder to be used by other getBuilderFor* method.
      *
      * @param int    $userId
      * @param string $sortBy
@@ -422,10 +448,23 @@ class EntryRepository extends EntityRepository
      *
      * @return QueryBuilder
      */
-    private function getBuilderByUser($userId, $sortBy = 'createdAt', $direction = 'desc')
+    private function getSortedQueryBuilderByUser($userId, $sortBy = 'createdAt', $direction = 'desc')
     {
-        return $this->createQueryBuilder('e')
-            ->andWhere('e.user = :userId')->setParameter('userId', $userId)
+        return $this->sortQueryBuilder($this->getQueryBuilderByUser($userId), $sortBy, $direction);
+    }
+
+    /**
+     * Return the given QueryBuilder with an orderBy() call.
+     *
+     * @param QueryBuilder $qb
+     * @param string       $sortBy
+     * @param string       $direction
+     *
+     * @return QueryBuilder
+     */
+    private function sortQueryBuilder(QueryBuilder $qb, $sortBy = 'createdAt', $direction = 'desc')
+    {
+        return $qb
             ->orderBy(sprintf('e.%s', $sortBy), $direction);
     }
 }
index 5c45211f6beb1e2820e9ed5ddba79f95c10a04df..3ae9d4141161c4443eb98f9bc6533695558e6143 100644 (file)
@@ -30,7 +30,7 @@ class TagRepository extends EntityRepository
             $query->setResultCacheLifetime($cacheLifeTime);
         }
 
-        return count($query->getArrayResult());
+        return \count($query->getArrayResult());
     }
 
     /**
index 8e6bbae01c8032b5482a30d35992906ebd4fd803..4fd4debdc4a542a61a1204fd433040ae6968a1a1 100644 (file)
@@ -1,5 +1,12 @@
 <div class="card">
     <div class="card-body">
+        <div class="card-image waves-effect waves-block waves-light">
+            <ul class="card-entry-labels">
+            {% for tag in entry.tags | slice(0, 3) %}
+                <li><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a></li>
+            {% endfor %}
+            </ul>
+        </div>
         {% include "@WallabagCore/themes/material/Entry/Card/_content.html.twig" with {'entry': entry} only %}
     </div>
 
index eba21c025d71cb86c79874f4c2ca26b978ffac66..46bb1dc5c82441cd8277f00dc121eec84298697e 100644 (file)
@@ -29,6 +29,6 @@ class Utils
      */
     public static function getReadingTime($text)
     {
-        return floor(count(preg_split('~[^\p{L}\p{N}\']+~u', strip_tags($text))) / 200);
+        return floor(\count(preg_split('~[^\p{L}\p{N}\']+~u', strip_tags($text))) / 200);
     }
 }
index 8992117e62baef07228a517238ca44aa06ddf2e6..00b1e595499d05f79de855e460a7a863af8a00a6 100644 (file)
@@ -64,7 +64,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
     {
         $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
 
-        if (null === $user || !is_object($user)) {
+        if (null === $user || !\is_object($user)) {
             return 0;
         }
 
@@ -96,7 +96,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
         $query->useResultCache(true);
         $query->setResultCacheLifetime($this->lifeTime);
 
-        return count($query->getArrayResult());
+        return \count($query->getArrayResult());
     }
 
     /**
@@ -108,7 +108,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
     {
         $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
 
-        if (null === $user || !is_object($user)) {
+        if (null === $user || !\is_object($user)) {
             return 0;
         }
 
@@ -124,7 +124,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
     {
         $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
 
-        if (null === $user || !is_object($user)) {
+        if (null === $user || !\is_object($user)) {
             return 0;
         }
 
@@ -137,7 +137,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
         $query->useResultCache(true);
         $query->setResultCacheLifetime($this->lifeTime);
 
-        $nbArchives = count($query->getArrayResult());
+        $nbArchives = \count($query->getArrayResult());
 
         $interval = $user->getCreatedAt()->diff(new \DateTime('now'));
         $nbDays = (int) $interval->format('%a') ?: 1;
index 99056c2c6b4c9cba4e0b47b7b36f24bdf6fcf779..f9ffe994db821fafb815b546871d4f1eb04ae034 100644 (file)
@@ -43,7 +43,7 @@ class ImportCommand extends ContainerAwareCommand
             $user = $em->getRepository('WallabagUserBundle:User')->findOneByUsername($input->getArgument('username'));
         }
 
-        if (!is_object($user)) {
+        if (!\is_object($user)) {
             throw new Exception(sprintf('User "%s" not found', $input->getArgument('username')));
         }
 
index 77a7a9040621f2915517e6c2dd07527e9c0181cc..6418925c0c9c21efb31f48a5f42007c3e84d996f 100644 (file)
@@ -30,7 +30,7 @@ abstract class BrowserController extends Controller
             $markAsRead = $form->get('mark_as_read')->getData();
             $name = $this->getUser()->getId() . '.json';
 
-            if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
+            if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
                 $res = $wallabag
                     ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
                     ->setMarkAsRead($markAsRead)
index 550679c371bd71f02251cfceaa5f38132f509806..f184baf91ee7b708c1525b0db22c90c5410bb9fe 100644 (file)
@@ -31,7 +31,7 @@ class InstapaperController extends Controller
             $markAsRead = $form->get('mark_as_read')->getData();
             $name = 'instapaper_' . $this->getUser()->getId() . '.csv';
 
-            if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
+            if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
                 $res = $instapaper
                     ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
                     ->setMarkAsRead($markAsRead)
index 0e57fd41b42785c81cbc747cca8cb5087631420a..6f54c69a0fd5d4fc1abb9cf8fc7a0c9850c9c883 100644 (file)
@@ -31,7 +31,7 @@ class PinboardController extends Controller
             $markAsRead = $form->get('mark_as_read')->getData();
             $name = 'pinboard_' . $this->getUser()->getId() . '.json';
 
-            if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
+            if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
                 $res = $pinboard
                     ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
                     ->setMarkAsRead($markAsRead)
index 59de24cb853835a923d2735e9e9b216d17a3359d..729a97a3bbb90bf39c526c6546043dd6cc1f59a7 100644 (file)
@@ -31,7 +31,7 @@ class ReadabilityController extends Controller
             $markAsRead = $form->get('mark_as_read')->getData();
             $name = 'readability_' . $this->getUser()->getId() . '.json';
 
-            if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
+            if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
                 $res = $readability
                     ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
                     ->setMarkAsRead($markAsRead)
index 6e6524b4cd151cd0c855d2101e91cbc44bc6af11..d182dd2ca23b3b46fb9e48406a8884ee67559cc0 100644 (file)
@@ -33,7 +33,7 @@ abstract class WallabagController extends Controller
             $markAsRead = $form->get('mark_as_read')->getData();
             $name = $this->getUser()->getId() . '.json';
 
-            if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
+            if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
                 $res = $wallabag
                     ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
                     ->setMarkAsRead($markAsRead)
index b5593180f7a0063a086df1c339fe0fe355401f5a..225f1791f5bfe6b6fdc04bba4a2d0abf9cc7c600 100644 (file)
@@ -77,7 +77,7 @@ abstract class BrowserImport extends AbstractImport
      */
     public function parseEntry(array $importedEntry)
     {
-        if ((!array_key_exists('guid', $importedEntry) || (!array_key_exists('id', $importedEntry))) && is_array(reset($importedEntry))) {
+        if ((!array_key_exists('guid', $importedEntry) || (!array_key_exists('id', $importedEntry))) && \is_array(reset($importedEntry))) {
             if ($this->producer) {
                 $this->parseEntriesForProducer($importedEntry);
 
index 7ab69e7a34ab5cffa9dca765060ff0b62c5f0229..e4f0970c0c3f41a531a9d548c46fdc175946e92c 100644 (file)
@@ -62,7 +62,7 @@ class InstapaperImport extends AbstractImport
         }
 
         $entries = [];
-        $handle = fopen($this->filepath, 'r');
+        $handle = fopen($this->filepath, 'rb');
         while (false !== ($data = fgetcsv($handle, 10240))) {
             if ('URL' === $data[0]) {
                 continue;
@@ -72,7 +72,7 @@ class InstapaperImport extends AbstractImport
             // BUT it can also be the status (since status = folder in Instapaper)
             // and we don't want archive, unread & starred to become a tag
             $tags = null;
-            if (false === in_array($data[3], ['Archive', 'Unread', 'Starred'], true)) {
+            if (false === \in_array($data[3], ['Archive', 'Unread', 'Starred'], true)) {
                 $tags = [$data[3]];
             }
 
index dddb87f4e561d4e075927a2f201423bf17c3916a..c1b35b7ef028a0e261d9a072e867246eca4816eb 100644 (file)
@@ -149,7 +149,7 @@ class PocketImport extends AbstractImport
         //  - first call get 5k offset 0
         //  - second call get 5k offset 5k
         //  - and so on
-        if (self::NB_ELEMENTS === count($entries['list'])) {
+        if (self::NB_ELEMENTS === \count($entries['list'])) {
             ++$run;
 
             return $this->import(self::NB_ELEMENTS * $run);
index a35c411e45110024a854d5c9c180e4d078eb87bb..b9bb525ab5f20422f388370fe1b44b8bca9d228c 100644 (file)
@@ -56,7 +56,7 @@ class WallabagV1Import extends WallabagImport
 
         // In case of a bad fetch in v1, replace title and content with v2 error strings
         // If fetching fails again, they will get this instead of the v1 strings
-        if (in_array($entry['title'], $this->untitled, true)) {
+        if (\in_array($entry['title'], $this->untitled, true)) {
             $data['title'] = $this->fetchingErrorMessageTitle;
             $data['html'] = $this->fetchingErrorMessage;
         }
index 35de47f94c387a6f0c8565c9ed9c3e408227d3ab..f58d1c12027f9bb5a6e259311f8b9ca19206832d 100644 (file)
@@ -28,7 +28,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase
         $this->assertSame(200, $client->getResponse()->getStatusCode());
 
         $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
-        $this->assertGreaterThan(count($nbClients), count($newNbClients));
+        $this->assertGreaterThan(\count($nbClients), \count($newNbClients));
 
         $this->assertGreaterThan(1, $alert = $crawler->filter('.settings ul li strong')->extract(['_text']));
         $this->assertContains('My app', $alert[0]);
@@ -65,7 +65,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase
 
         $crawler = $client->request('GET', '/developer');
         $this->assertSame(200, $client->getResponse()->getStatusCode());
-        $this->assertSame(count($nbClients), $crawler->filter('ul[class=collapsible] li')->count());
+        $this->assertSame(\count($nbClients), $crawler->filter('ul[class=collapsible] li')->count());
     }
 
     public function testDeveloperHowto()
index 9722986eba38840068d271a45104c3a4b50d87db..58b617f3d5bc9519d1e50fe165875b931a037ae4 100644 (file)
@@ -28,7 +28,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $this->assertSame($entry->getTitle(), $content['title']);
         $this->assertSame($entry->getUrl(), $content['url']);
-        $this->assertCount(count($entry->getTags()), $content['tags']);
+        $this->assertCount(\count($entry->getTags()), $content['tags']);
         $this->assertSame($entry->getUserName(), $content['user_name']);
         $this->assertSame($entry->getUserEmail(), $content['user_email']);
         $this->assertSame($entry->getUserId(), $content['user_id']);
@@ -127,7 +127,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertNotEmpty($content['_embedded']['items']);
         $this->assertGreaterThanOrEqual(1, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -154,7 +154,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertArrayHasKey('items', $content['_embedded']);
         $this->assertGreaterThanOrEqual(0, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -206,7 +206,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertArrayHasKey('items', $content['_embedded']);
         $this->assertGreaterThanOrEqual(1, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -250,7 +250,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertNotEmpty($content['_embedded']['items']);
         $this->assertGreaterThanOrEqual(1, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -278,7 +278,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertNotEmpty($content['_embedded']['items']);
         $this->assertGreaterThanOrEqual(1, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -305,7 +305,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertNotEmpty($content['_embedded']['items']);
         $this->assertGreaterThanOrEqual(1, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -342,7 +342,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertNotEmpty($content['_embedded']['items']);
         $this->assertGreaterThanOrEqual(1, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -370,7 +370,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
-        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertGreaterThanOrEqual(1, \count($content));
         $this->assertEmpty($content['_embedded']['items']);
         $this->assertSame(0, $content['total']);
         $this->assertSame(1, $content['page']);
@@ -608,7 +608,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
         $this->assertSame($entry->getId(), $content['id']);
         $this->assertSame($entry->getUrl(), $content['url']);
         $this->assertSame('New awesome title', $content['title']);
-        $this->assertGreaterThanOrEqual(1, count($content['tags']), 'We force only one tag');
+        $this->assertGreaterThanOrEqual(1, \count($content['tags']), 'We force only one tag');
         $this->assertSame(1, $content['user_id']);
         $this->assertSame('de_AT', $content['language']);
         $this->assertSame('http://preview.io/picture.jpg', $content['preview_picture']);
@@ -647,7 +647,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
 
         $this->assertSame($entry->getId(), $content['id']);
         $this->assertSame($entry->getUrl(), $content['url']);
-        $this->assertGreaterThanOrEqual(1, count($content['tags']), 'We force only one tag');
+        $this->assertGreaterThanOrEqual(1, \count($content['tags']), 'We force only one tag');
         $this->assertEmpty($content['published_by'], 'Authors were not saved because of an array instead of a string');
         $this->assertSame($previousContent, $content['content'], 'Ensure content has not moved');
         $this->assertSame($previousLanguage, $content['language'], 'Ensure language has not moved');
@@ -772,7 +772,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
             $this->markTestSkipped('No content found in db.');
         }
 
-        $nbTags = count($entry->getTags());
+        $nbTags = \count($entry->getTags());
 
         $newTags = 'tag1,tag2,tag3';
 
@@ -783,7 +783,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
         $this->assertArrayHasKey('tags', $content);
-        $this->assertSame($nbTags + 3, count($content['tags']));
+        $this->assertSame($nbTags + 3, \count($content['tags']));
 
         $entryDB = $this->client->getContainer()
             ->get('doctrine.orm.entity_manager')
@@ -813,7 +813,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
         }
 
         // hydrate the tags relations
-        $nbTags = count($entry->getTags());
+        $nbTags = \count($entry->getTags());
         $tag = $entry->getTags()[0];
 
         $this->client->request('DELETE', '/api/entries/' . $entry->getId() . '/tags/' . $tag->getId() . '.json');
@@ -823,7 +823,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
         $content = json_decode($this->client->getResponse()->getContent(), true);
 
         $this->assertArrayHasKey('tags', $content);
-        $this->assertSame($nbTags - 1, count($content['tags']));
+        $this->assertSame($nbTags - 1, \count($content['tags']));
     }
 
     public function testSaveIsArchivedAfterPost()
index a436be79613310179258d2ef7d41937560d2beaf..bf0068b4b1e0f6941afc5bc3b517699a1860890c 100644 (file)
@@ -174,7 +174,7 @@ class EntryControllerTest extends WallabagCoreTestCase
 
     public function testPostWithMultipleAuthors()
     {
-        $url = 'http://www.liberation.fr/planete/2017/04/05/donald-trump-et-xi-jinping-tentative-de-flirt-en-floride_1560768';
+        $url = 'https://www.liberation.fr/planete/2017/04/05/donald-trump-et-xi-jinping-tentative-de-flirt-en-floride_1560768';
         $this->logInAs('admin');
         $client = $this->getClient();
 
@@ -197,6 +197,7 @@ class EntryControllerTest extends WallabagCoreTestCase
             ->getRepository('WallabagCoreBundle:Entry')
             ->findByUrlAndUserId($url, $this->getLoggedInUserId());
 
+        $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
         $authors = $content->getPublishedBy();
         $this->assertSame('2017-04-05 19:26:13', $content->getPublishedAt()->format('Y-m-d H:i:s'));
         $this->assertSame('fr', $content->getLanguage());
@@ -524,7 +525,7 @@ class EntryControllerTest extends WallabagCoreTestCase
 
         $this->assertGreaterThan(1, $title = $crawler->filter('div[id=article] h1')->extract(['_text']));
         $this->assertContains('My updated title hehe :)', $title[0]);
-        $this->assertSame(1, count($stats = $crawler->filter('div[class=tools] ul[class=stats] li a[class=tool]')->extract(['_text'])));
+        $this->assertSame(1, \count($stats = $crawler->filter('div[class=tools] ul[class=stats] li a[class=tool]')->extract(['_text'])));
         $this->assertNotContains('example.io', trim($stats[0]));
     }
 
@@ -1325,16 +1326,12 @@ class EntryControllerTest extends WallabagCoreTestCase
                 'http://www.hao123.com/shequ?__noscript__-=1',
                 'zh_CN',
             ],
-            'de_AT' => [
-                'https://buy.garmin.com/de-AT/AT/catalog/product/compareResult.ep?compareProduct=112885&compareProduct=36728',
-                'de_AT',
-            ],
-            'ru_RU' => [
-                'http://netler.ru/ikt/windows-error-reporting.htm',
-                'ru_RU',
+            'ru' => [
+                'https://www.kp.ru/daily/26879.7/3921982/',
+                'ru',
             ],
             'pt_BR' => [
-                'http://precodoscombustiveis.com.br/postos/cidade/4121/pr/maringa',
+                'https://politica.estadao.com.br/noticias/eleicoes,campanha-catatonica,70002491983',
                 'pt_BR',
             ],
             'fucked_list_of_languages' => [
index ab7f23cc516a51acf4f959b39c8d7cc584745b89..6f3308e56f337bd1d02d8cc7a36fca40a844deba 100644 (file)
@@ -180,7 +180,7 @@ class ExportControllerTest extends WallabagCoreTestCase
 
         $this->assertGreaterThan(1, $csv);
         // +1 for title line
-        $this->assertSame(count($contentInDB) + 1, count($csv));
+        $this->assertSame(\count($contentInDB) + 1, \count($csv));
         $this->assertSame('Title;URL;Content;Tags;"MIME Type";Language;"Creation date"', $csv[0]);
         $this->assertContains($contentInDB[0]['title'], $csv[1]);
         $this->assertContains($contentInDB[0]['url'], $csv[1]);
@@ -272,7 +272,7 @@ class ExportControllerTest extends WallabagCoreTestCase
 
         $content = new \SimpleXMLElement($client->getResponse()->getContent());
         $this->assertGreaterThan(0, $content->count());
-        $this->assertSame(count($contentInDB), $content->count());
+        $this->assertSame(\count($contentInDB), $content->count());
         $this->assertNotEmpty('id', (string) $content->entry[0]->id);
         $this->assertNotEmpty('title', (string) $content->entry[0]->title);
         $this->assertNotEmpty('url', (string) $content->entry[0]->url);
index 5a973a7e0409988ff306e9ee1848ccf2c1c26a81..768f4c0789d5ef733105c0d8a15e03581440ab8f 100644 (file)
@@ -98,7 +98,7 @@ class TagControllerTest extends WallabagCoreTestCase
             $tags[$key] = $tag->getLabel();
         }
 
-        $this->assertGreaterThanOrEqual(2, count($tags));
+        $this->assertGreaterThanOrEqual(2, \count($tags));
         $this->assertNotFalse(array_search('foo2', $tags, true), 'Tag foo2 is assigned to the entry');
         $this->assertNotFalse(array_search('bar2', $tags, true), 'Tag bar2 is assigned to the entry');
     }
index 51df8de1bd8ccd94283aef19c2782ff15996b7ce..3f3c60d0fd943436f88759853b9ee5c950b554e2 100644 (file)
@@ -531,6 +531,250 @@ class ContentProxyTest extends TestCase
         $this->assertSame('1.1.1.1', $entry->getDomainName());
     }
 
+    public function testWebsiteWithValidUTF8Title_doNothing()
+    {
+        // You can use https://www.online-toolz.com/tools/text-hex-convertor.php to convert UTF-8 text <=> hex
+        // See http://graphemica.com for more info about the characters
+        // '😻ℤz' (U+1F63B or F09F98BB; U+2124 or E284A4; U+007A or 7A) in hexadecimal and UTF-8
+        $actualTitle = $this->hexToStr('F09F98BB' . 'E284A4' . '7A');
+
+        $tagger = $this->getTaggerMock();
+        $tagger->expects($this->once())
+            ->method('tag');
+
+        $graby = $this->getMockBuilder('Graby\Graby')
+            ->setMethods(['fetchContent'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $graby->expects($this->any())
+            ->method('fetchContent')
+            ->willReturn([
+                'html' => false,
+                'title' => $actualTitle,
+                'url' => '',
+                'content_type' => 'text/html',
+                'language' => '',
+            ]);
+
+        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $entry = new Entry(new User());
+        $proxy->updateEntry($entry, 'http://0.0.0.0');
+
+        // '😻ℤz' (U+1F63B or F09F98BB; U+2124 or E284A4; U+007A or 7A) in hexadecimal and UTF-8
+        $expectedTitle = 'F09F98BB' . 'E284A4' . '7A';
+        $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle()));
+    }
+
+    public function testWebsiteWithInvalidUTF8Title_removeInvalidCharacter()
+    {
+        // See http://graphemica.com for more info about the characters
+        // 'a€b' (61;80;62) in hexadecimal and WINDOWS-1252 - but 80 is a invalid UTF-8 character.
+        // The correct UTF-8 â‚¬ character (U+20AC) is E282AC
+        $actualTitle = $this->hexToStr('61' . '80' . '62');
+
+        $tagger = $this->getTaggerMock();
+        $tagger->expects($this->once())
+            ->method('tag');
+
+        $graby = $this->getMockBuilder('Graby\Graby')
+            ->setMethods(['fetchContent'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $graby->expects($this->any())
+            ->method('fetchContent')
+            ->willReturn([
+                'html' => false,
+                'title' => $actualTitle,
+                'url' => '',
+                'content_type' => 'text/html',
+                'language' => '',
+            ]);
+
+        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $entry = new Entry(new User());
+        $proxy->updateEntry($entry, 'http://0.0.0.0');
+
+        // 'ab' (61;62) because all invalid UTF-8 character (like 80) are removed
+        $expectedTitle = '61' . '62';
+        $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle()));
+    }
+
+    public function testPdfWithUTF16BETitle_convertToUTF8()
+    {
+        // See http://graphemica.com for more info about the characters
+        // '😻' (U+1F63B;D83DDE3B) in hexadecimal and as UTF16BE
+        $actualTitle = $this->hexToStr('D83DDE3B');
+
+        $tagger = $this->getTaggerMock();
+        $tagger->expects($this->once())
+            ->method('tag');
+
+        $graby = $this->getMockBuilder('Graby\Graby')
+            ->setMethods(['fetchContent'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $graby->expects($this->any())
+            ->method('fetchContent')
+            ->willReturn([
+                'html' => false,
+                'title' => $actualTitle,
+                'url' => '',
+                'content_type' => 'application/pdf',
+                'language' => '',
+            ]);
+
+        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $entry = new Entry(new User());
+        $proxy->updateEntry($entry, 'http://0.0.0.0');
+
+        // '😻' (U+1F63B or F09F98BB) in hexadecimal and UTF-8
+        $expectedTitle = 'F09F98BB';
+        $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle()));
+    }
+
+    public function testPdfWithUTF8Title_doNothing()
+    {
+        // See http://graphemica.com for more info about the characters
+        // '😻' (U+1F63B;D83DDE3B) in hexadecimal and as UTF8
+        $actualTitle = $this->hexToStr('F09F98BB');
+
+        $tagger = $this->getTaggerMock();
+        $tagger->expects($this->once())
+            ->method('tag');
+
+        $graby = $this->getMockBuilder('Graby\Graby')
+            ->setMethods(['fetchContent'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $graby->expects($this->any())
+            ->method('fetchContent')
+            ->willReturn([
+                'html' => false,
+                'title' => $actualTitle,
+                'url' => '',
+                'content_type' => 'application/pdf',
+                'language' => '',
+            ]);
+
+        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $entry = new Entry(new User());
+        $proxy->updateEntry($entry, 'http://0.0.0.0');
+
+        // '😻' (U+1F63B or F09F98BB) in hexadecimal and UTF-8
+        $expectedTitle = 'F09F98BB';
+        $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle()));
+    }
+
+    public function testPdfWithWINDOWS1252Title_convertToUTF8()
+    {
+        // See http://graphemica.com for more info about the characters
+        // '€' (80) in hexadecimal and WINDOWS-1252
+        $actualTitle = $this->hexToStr('80');
+
+        $tagger = $this->getTaggerMock();
+        $tagger->expects($this->once())
+            ->method('tag');
+
+        $graby = $this->getMockBuilder('Graby\Graby')
+            ->setMethods(['fetchContent'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $graby->expects($this->any())
+            ->method('fetchContent')
+            ->willReturn([
+                'html' => false,
+                'title' => $actualTitle,
+                'url' => '',
+                'content_type' => 'application/pdf',
+                'language' => '',
+            ]);
+
+        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $entry = new Entry(new User());
+        $proxy->updateEntry($entry, 'http://0.0.0.0');
+
+        // '€' (U+20AC or E282AC) in hexadecimal and UTF-8
+        $expectedTitle = 'E282AC';
+        $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle()));
+    }
+
+    public function testPdfWithInvalidCharacterInTitle_removeInvalidCharacter()
+    {
+        // See http://graphemica.com for more info about the characters
+        // '😻ℤ�z' (U+1F63B or F09F98BB; U+2124 or E284A4; invalid character 81; U+007A or 7A) in hexadecimal and UTF-8
+        // 0x81 is not a valid character for UTF16, UTF8 and WINDOWS-1252
+        $actualTitle = $this->hexToStr('F09F98BB' . 'E284A4' . '81' . '7A');
+
+        $tagger = $this->getTaggerMock();
+        $tagger->expects($this->once())
+            ->method('tag');
+
+        $graby = $this->getMockBuilder('Graby\Graby')
+            ->setMethods(['fetchContent'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $graby->expects($this->any())
+            ->method('fetchContent')
+            ->willReturn([
+                'html' => false,
+                'title' => $actualTitle,
+                'url' => '',
+                'content_type' => 'application/pdf',
+                'language' => '',
+            ]);
+
+        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $entry = new Entry(new User());
+        $proxy->updateEntry($entry, 'http://0.0.0.0');
+
+        // '😻ℤz' (U+1F63B or F09F98BB; U+2124 or E284A4; U+007A or 7A) in hexadecimal and UTF-8
+        // the 0x81 (represented by ï¿½) is invalid for UTF16, UTF8 and WINDOWS-1252 and is removed
+        $expectedTitle = 'F09F98BB' . 'E284A4' . '7A';
+        $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle()));
+    }
+
+    /**
+     * https://stackoverflow.com/a/18506801.
+     *
+     * @param $string
+     *
+     * @return string
+     */
+    private function strToHex($string)
+    {
+        $hex = '';
+        for ($i = 0; $i < \strlen($string); ++$i) {
+            $ord = \ord($string[$i]);
+            $hexCode = dechex($ord);
+            $hex .= substr('0' . $hexCode, -2);
+        }
+
+        return strtoupper($hex);
+    }
+
+    /**
+     * https://stackoverflow.com/a/18506801.
+     *
+     * @param $hex
+     *
+     * @return string
+     */
+    private function hexToStr($hex)
+    {
+        $string = '';
+        for ($i = 0; $i < \strlen($hex) - 1; $i += 2) {
+            $string .= \chr(hexdec($hex[$i] . $hex[$i + 1]));
+        }
+
+        return $string;
+    }
+
     private function getTaggerMock()
     {
         return $this->getMockBuilder(RuleBasedTagger::class)
index ddb7a65a86bf50cce9789d493e030550b4483dd0..cd3e41e98e7d83b8d88c9687d2f91028cd7fbb67 100644 (file)
@@ -121,7 +121,7 @@ class ChromeControllerTest extends WallabagCoreTestCase
         $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
         $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for http://www.usinenouvelle.com is ok');
         $this->assertNotEmpty($content->getLanguage(), 'Language for http://www.usinenouvelle.com is ok');
-        $this->assertSame(1, count($content->getTags()));
+        $this->assertSame(1, \count($content->getTags()));
 
         $createdAt = $content->getCreatedAt();
         $this->assertSame('2011', $createdAt->format('Y'));
index fc02c81344bdaa79b5e022fde4c41a62f489f374..dc5ed6d0c851198f8f3baacb7cadd5246e8d9096 100644 (file)
@@ -122,7 +122,7 @@ class FirefoxControllerTest extends WallabagCoreTestCase
         $this->assertNotEmpty($content->getMimetype(), 'Mimetype for http://lexpansion.lexpress.fr is ok');
         $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for http://lexpansion.lexpress.fr is ok');
         $this->assertNotEmpty($content->getLanguage(), 'Language for http://lexpansion.lexpress.fr is ok');
-        $this->assertSame(3, count($content->getTags()));
+        $this->assertSame(3, \count($content->getTags()));
 
         $content = $client->getContainer()
             ->get('doctrine.orm.entity_manager')
index dacdf4883cab9641382c551b89b4a636ef6ce58e..7390fa8849a33965e67cc0be886e4f50ce269f3f 100644 (file)
@@ -114,15 +114,17 @@ class InstapaperControllerTest extends WallabagCoreTestCase
             ->get('doctrine.orm.entity_manager')
             ->getRepository('WallabagCoreBundle:Entry')
             ->findByUrlAndUserId(
-                'http://www.liberation.fr/societe/2012/12/06/baumettes-un-tour-en-cellule_865551',
+                'https://www.liberation.fr/societe/2012/12/06/baumettes-un-tour-en-cellule_865551',
                 $this->getLoggedInUserId()
             );
 
-        $this->assertNotEmpty($content->getMimetype(), 'Mimetype for http://www.liberation.fr is ok');
-        $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for http://www.liberation.fr is ok');
-        $this->assertNotEmpty($content->getLanguage(), 'Language for http://www.liberation.fr is ok');
+        $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
+
+        $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.liberation.fr is ok');
+        $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.liberation.fr is ok');
+        $this->assertNotEmpty($content->getLanguage(), 'Language for https://www.liberation.fr is ok');
         $this->assertContains('foot', $content->getTags(), 'It includes the "foot" tag');
-        $this->assertSame(1, count($content->getTags()));
+        $this->assertSame(1, \count($content->getTags()));
         $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
 
         $content = $client->getContainer()
@@ -136,7 +138,7 @@ class InstapaperControllerTest extends WallabagCoreTestCase
         $this->assertContains('foot', $content->getTags());
         $this->assertContains('test_tag', $content->getTags());
 
-        $this->assertSame(2, count($content->getTags()));
+        $this->assertSame(2, \count($content->getTags()));
     }
 
     public function testImportInstapaperWithFileAndMarkAllAsRead()
index 1135f32e90e8c675143b374ce5b53363a2e772ca..80819f45757f4699dcdd09b6f24e8dab843ae266 100644 (file)
@@ -127,7 +127,7 @@ class PinboardControllerTest extends WallabagCoreTestCase
         $this->assertContains('foot', $tags, 'It includes the "foot" tag');
         $this->assertContains('varnish', $tags, 'It includes the "varnish" tag');
         $this->assertContains('php', $tags, 'It includes the "php" tag');
-        $this->assertSame(3, count($tags));
+        $this->assertSame(3, \count($tags));
 
         $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
         $this->assertSame('2016-10-26', $content->getCreatedAt()->format('Y-m-d'));
index 78816ad884fe2dca9783e94a717962cdd0219883..5619659adab49f43462fc748b4295b440d0f0ce0 100644 (file)
@@ -125,7 +125,7 @@ class ReadabilityControllerTest extends WallabagCoreTestCase
 
         $tags = $content->getTags();
         $this->assertContains('foot', $tags, 'It includes the "foot" tag');
-        $this->assertSame(1, count($tags));
+        $this->assertSame(1, \count($tags));
 
         $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
         $this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d'));
index e0e309b0158fca4a2ed70582e42c11d0d009b5ae..c67941a71046813cabd5b3d227b42a79d43eb24b 100644 (file)
@@ -127,7 +127,7 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase
         $tags = $content->getTags();
         $this->assertContains('foot', $tags, 'It includes the "foot" tag');
         $this->assertContains('framabag', $tags, 'It includes the "framabag" tag');
-        $this->assertSame(2, count($tags));
+        $this->assertSame(2, \count($tags));
 
         $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
     }
index e52b9c85f563d2f7e31d9564d7cf7812963d3aea..822656ba4ba0789d05c9f93924fefbcddaa83e02 100644 (file)
@@ -115,20 +115,20 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase
             ->get('doctrine.orm.entity_manager')
             ->getRepository('WallabagCoreBundle:Entry')
             ->findByUrlAndUserId(
-                'http://www.liberation.fr/planete/2015/10/26/refugies-l-ue-va-creer-100-000-places-d-accueil-dans-les-balkans_1408867',
+                'https://www.liberation.fr/planete/2015/10/26/refugies-l-ue-va-creer-100-000-places-d-accueil-dans-les-balkans_1408867',
                 $this->getLoggedInUserId()
             );
 
         $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
 
         // empty because it wasn't re-imported
-        $this->assertEmpty($content->getMimetype(), 'Mimetype for http://www.liberation.fr is empty');
-        $this->assertEmpty($content->getPreviewPicture(), 'Preview picture for http://www.liberation.fr is empty');
-        $this->assertEmpty($content->getLanguage(), 'Language for http://www.liberation.fr is empty');
+        $this->assertEmpty($content->getMimetype(), 'Mimetype for https://www.liberation.fr is empty');
+        $this->assertEmpty($content->getPreviewPicture(), 'Preview picture for https://www.liberation.fr is empty');
+        $this->assertEmpty($content->getLanguage(), 'Language for https://www.liberation.fr is empty');
 
         $tags = $content->getTags();
         $this->assertContains('foot', $tags, 'It includes the "foot" tag');
-        $this->assertSame(1, count($tags));
+        $this->assertSame(1, \count($tags));
 
         $content = $client->getContainer()
             ->get('doctrine.orm.entity_manager')
@@ -147,7 +147,7 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase
         $this->assertContains('foot', $tags, 'It includes the "foot" tag');
         $this->assertContains('mediapart', $tags, 'It includes the "mediapart" tag');
         $this->assertContains('blog', $tags, 'It includes the "blog" tag');
-        $this->assertSame(3, count($tags));
+        $this->assertSame(3, \count($tags));
 
         $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
         $this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d'));
index 7b692d00d859a68572c75626b8f9249759254b91..5380bf2ce3df548d2eea9e1c78fc53a32df4ab0d 100644 (file)
@@ -1,5 +1,5 @@
 URL,Title,Selection,Folder
-http://www.liberation.fr/societe/2012/12/06/baumettes-un-tour-en-cellule_865551,Baumettes : un tour en cellule,,Unread
+https://www.liberation.fr/societe/2012/12/06/baumettes-un-tour-en-cellule_865551,Baumettes : un tour en cellule,,Unread
 https://redditblog.com/2016/09/20/amp-and-reactredux/,AMP and React+Redux: Why Not?,,Archive
 https://medium.com/@the_minh/why-foursquare-swarm-is-still-my-favourite-social-network-e38228493e6c,Why Foursquare / Swarm is still my favourite social network,,Starred
 https://www.20minutes.fr/high-tech/2077615-20170531-quoi-exactement-tweet-covfefe-donald-trump-persiste-signe,"Dis donc Donald Trump, c'est quoi exactement Â«covfefe»?",,test_tag
index 63c44cf9eb5eddbd1392eff48cee203037818368..a2142f90019d9de609c5ec0cafa9f43b4ea3f80e 100644 (file)
@@ -21,7 +21,7 @@
     {
         "id": 22,
         "title": "Réfugiés: l'UE va créer 100 000 places d'accueil dans les Balkans",
-        "url": "http://www.liberation.fr/planete/2015/10/26/refugies-l-ue-va-creer-100-000-places-d-accueil-dans-les-balkans_1408867",
+        "url": "https://www.liberation.fr/planete/2015/10/26/refugies-l-ue-va-creer-100-000-places-d-accueil-dans-les-balkans_1408867",
         "is_archived": false,
         "created_at": "2016-09-08T11:55:58+0200",
         "updated_at": "2016-09-08T11:57:16+0200",
index f39fa60e6a3cf3d5bb53104cbd414346b4d2bffd..aa1760688232603c85b775a851311b1c2104cb4d 100644 (file)
@@ -13,7 +13,7 @@ final class CountableMemorySpool extends \Swift_MemorySpool implements \Countabl
 {
     public function count()
     {
-        return count($this->messages);
+        return \count($this->messages);
     }
 
     public function getMessages()
index 3b14a4022d4324a35c42e6f9b8d91150053fedc2..4a1fcc62128bd873f3096e4899e147c96fc050b6 100644 (file)
@@ -389,7 +389,7 @@ class SymfonyRequirements extends RequirementCollection
     {
         /* mandatory requirements follow */
 
-        $installedPhpVersion = phpversion();
+        $installedPhpVersion = PHP_VERSION;
         $requiredPhpVersion = $this->getPhpRequiredVersion();
 
         $this->addRecommendation(
@@ -448,15 +448,8 @@ class SymfonyRequirements extends RequirementCollection
         }
 
         if (false !== $requiredPhpVersion && version_compare($installedPhpVersion, $requiredPhpVersion, '>=')) {
-            $timezones = array();
-            foreach (DateTimeZone::listAbbreviations() as $abbreviations) {
-                foreach ($abbreviations as $abbreviation) {
-                    $timezones[$abbreviation['timezone_id']] = true;
-                }
-            }
-
             $this->addRequirement(
-                isset($timezones[@date_default_timezone_get()]),
+                in_array(@date_default_timezone_get(), DateTimeZone::listIdentifiers(), true),
                 sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()),
                 'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.'
             );
@@ -731,7 +724,7 @@ class SymfonyRequirements extends RequirementCollection
             'Install and/or enable a <strong>PHP accelerator</strong> (highly recommended).'
         );
 
-        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+        if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
             $this->addRecommendation(
                 $this->getRealpathCacheSize() >= 5 * 1024 * 1024,
                 'realpath_cache_size should be at least 5M in php.ini',
index 1dd45be40b8056f23b6f8b0c07863a17be76eddf..7b62e0f9c34db9f035b69a9d4698fb0e9ecd5abb 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -2178,6 +2178,10 @@ hawk@~3.1.3:
     hoek "2.x.x"
     sntp "1.x.x"
 
+highlight.js@^9.12.0:
+  version "9.12.0"
+  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
+
 hmac-drbg@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"