Merge remote-tracking branch 'origin/master' into 2.4

This commit is contained in:
Jeremy Benoist 2018-09-07 13:46:30 +02:00
commit 7083c0a21d
No known key found for this signature in database
GPG key ID: BCA73962457ACC3C
76 changed files with 246 additions and 744 deletions

View file

@ -44,7 +44,6 @@ matrix:
- php: 7.0 - php: 7.0
env: CS_FIXER=run VALIDATE_TRANSLATION_FILE=run ASSETS=build DB=sqlite env: CS_FIXER=run VALIDATE_TRANSLATION_FILE=run ASSETS=build DB=sqlite
allow_failures: allow_failures:
- php: 7.2
- php: nightly - php: nightly
# exclude v1 branches # exclude v1 branches

View file

@ -24,6 +24,11 @@ cd wallabag && make install
Now, [configure a virtual host](https://doc.wallabag.org/en/admin/installation/virtualhosts.html) to use your wallabag. Now, [configure a virtual host](https://doc.wallabag.org/en/admin/installation/virtualhosts.html) to use your wallabag.
# Run on YunoHost
[![Install Wallabag with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=wallabag2)
Wallabag app for [YunoHost](https://yunohost.org). See [here](https://github.com/YunoHost-Apps/wallabag2_ynh)
# License # License
Copyright © 2013-2018 Nicolas Lœuillet <nicolas@loeuillet.org> Copyright © 2013-2018 Nicolas Lœuillet <nicolas@loeuillet.org>
This work is free. You can redistribute it and/or modify it under the This work is free. You can redistribute it and/or modify it under the

View file

@ -55,7 +55,7 @@ class Version20170719231144 extends WallabagMigration
} }
// Just in case... // Just in case...
if (count($ids) > 0) { if (\count($ids) > 0) {
// Merge tags // Merge tags
$this->addSql(' $this->addSql('
UPDATE ' . $this->getTable('entry_tag') . ' UPDATE ' . $this->getTable('entry_tag') . '

View file

@ -27,7 +27,7 @@ export: "export"
import: "import" import: "import"
misc: "misc" misc: "misc"
modify_settings: "apply" modify_settings: "apply"
piwik_host: Host of your website in Piwik (without http:// ou https://) piwik_host: Host of your website in Piwik (without http:// or https://)
piwik_site_id: ID of your website in Piwik piwik_site_id: ID of your website in Piwik
piwik_enabled: Enable Piwik piwik_enabled: Enable Piwik
demo_mode_enabled: "Enable demo mode? (Only used for the public wallabag demo)" demo_mode_enabled: "Enable demo mode? (Only used for the public wallabag demo)"
@ -37,4 +37,4 @@ download_images_enabled: Download images locally
restricted_access: Enable authentication for paywalled websites restricted_access: Enable authentication for paywalled websites
api_user_registration: Enable user to be registered using the API api_user_registration: Enable user to be registered using the API
store_article_headers: Enable if wallabag stores HTTP headers for each article store_article_headers: Enable if wallabag stores HTTP headers for each article
shaarli_share_origin_url: Enable sharing origin url to Shaarli, if the service is enabled shaarli_share_origin_url: Enable sharing origin url to Shaarli, if the service is enabled

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path fill="none" d="M0 0h200v200H0z"/><path d="M75.899 72.438c1.597-.981 10.207-5.556 24.098.178 14.289 5.897 23.154.776 24.253.079-3.454-5.678-7.562-10.62-12.104-13.943.303-.083.612-.167.939-.263 6.023-1.742 7.553-6.842 7.875-11.21.364-4.954.616-5.03 1.692-9.487 1.032-4.281-.119-5.137-1.181-4.273-.572.465-5.552 1.616-8.505 3.919-4.768 3.72-7.707 10.794-9.039 14.706-.025.06-.205.604-.265.792-.621 1.498-1.857 1.494-1.857 1.494v.001c-.6-.065-1.202-.1-1.809-.1-.54 0-1.079.029-1.616.081-.012.002-.019 0-.031.001-1.581.233-2.45-1.697-2.632-2.157-1.847-5.304-6.816-15.763-17.984-18.577 0 0-2.028-1.554-1.41 1.074.588 2.511 1.804 5.049 1.534 8.741-.124 1.704-1.181 10.442 6.85 14.99.763.432 1.441.795 2.051 1.101-4.042 3.235-7.716 7.74-10.859 12.853zM128.626 152.353c-9.842-6.098-13.153-8.242-12.946-10.575 0 0 .002-.379.099-.957.239-1.236.995-3.348 3.407-4.552.079-.039.146-.084.208-.129 7.668-4.45 13.27-11.614 15.246-20.56-1.99 4.941-16.735 8.78-34.645 8.78-17.903 0-32.651-3.839-34.641-8.78.442 2.008 1.073 3.923 1.864 5.742.666 3.745 1.562 12.563-2.673 20.282-3.731 6.8-22.15 16.069-49.485 10.748 0 0-1.096-.766-1.428-.136-.491.932 1.517 1.685 3.583 2.229 19.031 5.04 47.756 2.989 56.777-4.443 4.116-3.388 5.704-7.953 6.107-12.865l.003.008s.11-1.287 1.719-.32c.461.277 2.125 1.36 2.39 2.585.232 1.743.248 3.883-.652 5.382-1.287 2.144-1.301 2.452.393 3.662 1.04.742 5.287 3.864 11.198 7.415.015.01.023.019.038.027 1.25.753 2.987 2.597 2.987 2.597 2.662 3.079 8.452 9.275 10.972 8.108 1.19-.551-.051-3.032-.051-3.032s1.98 2.571 3.043 1.694c.809-.668-.473-3.229-.473-3.229s1.729 1.499 2.757.944c1.258-.679-.187-4.614-10.079-10.627-9.896-6.018-12.578-6.94-12.814-9.626 0 0-.004-.135.004-.366.077-.593.414-1.847 1.852-1.712 2.141.346 4.348.531 6.608.531 2.587 0 5.107-.237 7.536-.69l.001.003s.127-.025.164-.031c.284-.036.838-.018.84.671-.09.873-.331 1.751-.845 2.519-1.447 2.168-.972 2.466.54 3.859.933.859 5.211 4.622 11.07 8.264.012.009.017.016.031.023 1.249.752 3.41 2.816 3.41 2.816v-.001c2.428 2.466 6.894 6.596 9.327 6.347 1.646-.168.306-3.002.306-3.002s2.078 2.006 3.099 1.416c1.142-.659-.474-2.755-.474-2.755s1.338.708 2.283.473c.948-.236 1.185-2.644-8.656-8.737z"/><path d="M117.631 83.452c-1.181 0-2.161.355-2.912 1.057-.76.71-1.144 1.531-1.144 2.438v16.056c0 2.154-.382 3.742-1.135 4.721-.728.946-1.892 1.406-3.556 1.406-1.703 0-2.863-.457-3.549-1.396-.716-.979-1.078-2.571-1.078-4.731V86.884c0-1.098-.5-1.996-1.448-2.596-1.289-.812-2.57-1.105-4.129-.587-.476.159-.924.366-1.333.615-.435.265-.802.597-1.093.985-.322.432-.486.901-.486 1.396v16.307c0 2.158-.363 3.75-1.079 4.73-.688.939-1.849 1.396-3.548 1.396-1.705 0-2.877-.459-3.584-1.401-.734-.979-1.107-2.57-1.107-4.726V86.947c0-.908-.384-1.728-1.145-2.438-.751-.702-1.751-1.057-2.973-1.057-1.258 0-2.296.352-3.085 1.045-.811.71-1.222 1.535-1.222 2.45v15.806c0 1.988.194 3.869.575 5.588.393 1.758 1.077 3.3 2.035 4.586.968 1.299 2.282 2.323 3.906 3.05 1.607.716 3.617 1.079 5.975 1.079 2.457 0 4.515-.455 6.115-1.354 1.342-.754 2.473-1.744 3.371-2.951.866 1.207 1.971 2.197 3.294 2.95 1.58.899 3.669 1.354 6.211 1.354 2.357 0 4.359-.364 5.947-1.081 1.601-.726 2.902-1.751 3.872-3.048.96-1.29 1.645-2.833 2.034-4.586.381-1.719.575-3.6.575-5.588V86.947c0-.911-.398-1.733-1.184-2.445-.767-.697-1.818-1.05-3.12-1.05z"/></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -221,6 +221,12 @@ ol li:last-child {
padding-bottom: 0; padding-bottom: 0;
} }
iframe,
video {
max-width: 100%;
height: auto;
}
mark { mark {
padding: 0 0.2em; padding: 0 0.2em;
} }

View file

@ -24,6 +24,10 @@ main,
height: 100%; height: 100%;
} }
.typo-logo {
max-width: 150px;
}
#main { #main {
flex: 1 0 auto; flex: 1 0 auto;

View file

@ -26,7 +26,6 @@ framework:
engines: ['twig'] engines: ['twig']
default_locale: "%locale%" default_locale: "%locale%"
trusted_hosts: ~ trusted_hosts: ~
trusted_proxies: ~
session: session:
# handler_id set to null will use default session handler from php.ini # handler_id set to null will use default session handler from php.ini
handler_id: session.handler.native_file handler_id: session.handler.native_file

View file

@ -1,6 +1,6 @@
#! /usr/bin/env bash #! /usr/bin/env bash
# You can execute this file to create a new package for wallabag # 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 VERSION=$1
TMP_FOLDER=$2 TMP_FOLDER=$2
@ -10,11 +10,11 @@ ENV=$4
rm -rf $TMP_FOLDER/$RELEASE_FOLDER rm -rf $TMP_FOLDER/$RELEASE_FOLDER
mkdir $TMP_FOLDER/$RELEASE_FOLDER mkdir $TMP_FOLDER/$RELEASE_FOLDER
git clone git@github.com:wallabag/wallabag.git -b $VERSION $TMP_FOLDER/$RELEASE_FOLDER/$VERSION 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 wallabag:install --env=$ENV
cd $TMP_FOLDER/$RELEASE_FOLDER/$VERSION && php bin/console assets:install --env=$ENV --symlink --relative 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 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" echo "MD5 checksum of the package for wallabag $VERSION"
md5 $TMP_FOLDER/$RELEASE_FOLDER/wallabag-$VERSION.tar.gz 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 echo "Package to upload to the release server:"
rm -rf $TMP_FOLDER/$RELEASE_FOLDER echo $TMP_FOLDER/$RELEASE_FOLDER/wallabag-$VERSION.tar.gz

View file

@ -28,7 +28,7 @@ class WallabagAnnotationController extends FOSRestController
->getDoctrine() ->getDoctrine()
->getRepository('WallabagAnnotationBundle:Annotation') ->getRepository('WallabagAnnotationBundle:Annotation')
->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId()); ->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId());
$total = count($annotationRows); $total = \count($annotationRows);
$annotations = ['total' => $total, 'rows' => $annotationRows]; $annotations = ['total' => $total, 'rows' => $annotationRows];
$json = $this->get('jms_serializer')->serialize($annotations, 'json'); $json = $this->get('jms_serializer')->serialize($annotations, 'json');

View file

@ -21,7 +21,7 @@ class AnnotationRepository extends EntityRepository
public function getBuilderForAllByUser($userId) public function getBuilderForAllByUser($userId)
{ {
return $this return $this
->getBuilderByUser($userId) ->getSortedQueryBuilderByUser($userId)
; ;
} }
@ -133,7 +133,7 @@ class AnnotationRepository extends EntityRepository
* *
* @return QueryBuilder * @return QueryBuilder
*/ */
private function getBuilderByUser($userId) private function getSortedQueryBuilderByUser($userId)
{ {
return $this->createQueryBuilder('a') return $this->createQueryBuilder('a')
->leftJoin('a.user', 'u') ->leftJoin('a.user', 'u')

View file

@ -102,7 +102,7 @@ class EntryRestController extends WallabagRestController
$order = $request->query->get('order', 'desc'); $order = $request->query->get('order', 'desc');
$page = (int) $request->query->get('page', 1); $page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', 30); $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); $since = $request->query->get('since', 0);
/** @var \Pagerfanta\Pagerfanta $pager */ /** @var \Pagerfanta\Pagerfanta $pager */
@ -253,7 +253,7 @@ class EntryRestController extends WallabagRestController
$limit = $this->container->getParameter('wallabag_core.api_limit_mass_actions'); $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'); throw new HttpException(400, 'API limit reached');
} }
@ -347,7 +347,7 @@ class EntryRestController extends WallabagRestController
'open_graph' => [ 'open_graph' => [
'og_image' => !empty($data['picture']) ? $data['picture'] : $entry->getPreviewPicture(), '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) { } catch (\Exception $e) {
@ -461,7 +461,7 @@ class EntryRestController extends WallabagRestController
$contentProxy->updateLanguage($entry, $data['language']); $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'])); $entry->setPublishedBy(explode(',', $data['authors']));
} }

View file

@ -138,14 +138,14 @@ class TagRestController extends WallabagRestController
*/ */
private function cleanOrphanTag($tags) private function cleanOrphanTag($tags)
{ {
if (!is_array($tags)) { if (!\is_array($tags)) {
$tags = [$tags]; $tags = [$tags];
} }
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
foreach ($tags as $tag) { foreach ($tags as $tag) {
if (0 === count($tag->getEntries())) { if (0 === \count($tag->getEntries())) {
$em->remove($tag); $em->remove($tag);
} }
} }

View file

@ -51,7 +51,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
} else { } else {
$users = $this->getContainer()->get('wallabag_user.user_repository')->findAll(); $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) { foreach ($users as $user) {
$this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername())); $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername()));
@ -79,7 +79,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
$url = $this->similarUrl($entry['url']); $url = $this->similarUrl($entry['url']);
/* @var $entry Entry */ /* @var $entry Entry */
if (in_array($url, $urls, true)) { if (\in_array($url, $urls, true)) {
++$duplicatesCount; ++$duplicatesCount;
$em->remove($repo->find($entry['id'])); $em->remove($repo->find($entry['id']));
@ -96,8 +96,8 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
private function similarUrl($url) private function similarUrl($url)
{ {
if (in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls if (\in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls
return substr($url, 0, strlen($url)); return substr($url, 0, \strlen($url));
} }
return $url; return $url;

View file

@ -47,7 +47,7 @@ class ExportCommand extends ContainerAwareCommand
->getQuery() ->getQuery()
->getResult(); ->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'); $filePath = $input->getArgument('filepath');

View file

@ -81,7 +81,7 @@ class InstallCommand extends ContainerAwareCommand
$status = '<info>OK!</info>'; $status = '<info>OK!</info>';
$help = ''; $help = '';
if (!extension_loaded($this->getContainer()->getParameter('database_driver'))) { if (!\extension_loaded($this->getContainer()->getParameter('database_driver'))) {
$fulfilled = false; $fulfilled = false;
$status = '<error>ERROR!</error>'; $status = '<error>ERROR!</error>';
$help = 'Database driver "' . $this->getContainer()->getParameter('database_driver') . '" is not installed.'; $help = 'Database driver "' . $this->getContainer()->getParameter('database_driver') . '" is not installed.';
@ -146,7 +146,7 @@ class InstallCommand extends ContainerAwareCommand
$status = '<info>OK!</info>'; $status = '<info>OK!</info>';
$help = ''; $help = '';
if (!function_exists($functionRequired)) { if (!\function_exists($functionRequired)) {
$fulfilled = false; $fulfilled = false;
$status = '<error>ERROR!</error>'; $status = '<error>ERROR!</error>';
$help = 'You need the ' . $functionRequired . ' function activated'; $help = 'You need the ' . $functionRequired . ' function activated';
@ -371,7 +371,7 @@ class InstallCommand extends ContainerAwareCommand
} }
try { try {
return in_array($databaseName, $schemaManager->listDatabases(), true); return \in_array($databaseName, $schemaManager->listDatabases(), true);
} catch (\Doctrine\DBAL\Exception\DriverException $e) { } catch (\Doctrine\DBAL\Exception\DriverException $e) {
// it means we weren't able to get database list, assume the database doesn't exist // 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(); $schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager();
return count($schemaManager->listTableNames()) > 0 ? true : false; return \count($schemaManager->listTableNames()) > 0 ? true : false;
} }
} }

View file

@ -50,7 +50,7 @@ class ListUserCommand extends ContainerAwareCommand
$io->success( $io->success(
sprintf( sprintf(
'%s/%s%s user(s) displayed.', '%s/%s%s user(s) displayed.',
count($users), \count($users),
$nbUsers, $nbUsers,
null === $input->getArgument('search') ? '' : ' (filtered)' null === $input->getArgument('search') ? '' : ' (filtered)'
) )

View file

@ -43,7 +43,7 @@ class ReloadEntryCommand extends ContainerAwareCommand
$entryRepository = $this->getContainer()->get('wallabag_core.entry_repository'); $entryRepository = $this->getContainer()->get('wallabag_core.entry_repository');
$entryIds = $entryRepository->findAllEntriesIdByUserId($userId); $entryIds = $entryRepository->findAllEntriesIdByUserId($userId);
$nbEntries = count($entryIds); $nbEntries = \count($entryIds);
if (!$nbEntries) { if (!$nbEntries) {
$io->success('No entry to reload.'); $io->success('No entry to reload.');

View file

@ -348,7 +348,7 @@ class ConfigController extends Controller
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
foreach ($tags as $tag) { foreach ($tags as $tag) {
if (0 === count($tag->getEntries())) { if (0 === \count($tag->getEntries())) {
$em->remove($tag); $em->remove($tag);
} }
} }

View file

@ -65,7 +65,7 @@ class TagController extends Controller
$em->flush(); $em->flush();
// remove orphan tag in case no entries are associated to it // 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->remove($tag);
$em->flush(); $em->flush();
} }

View file

@ -33,7 +33,7 @@ class EntryFilterType extends AbstractType
$this->user = $tokenStorage->getToken() ? $tokenStorage->getToken()->getUser() : null; $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; return;
} }
} }
@ -96,7 +96,7 @@ class EntryFilterType extends AbstractType
->add('domainName', TextFilterType::class, [ ->add('domainName', TextFilterType::class, [
'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
$value = $values['value']; $value = $values['value'];
if (strlen($value) <= 2 || empty($value)) { if (\strlen($value) <= 2 || empty($value)) {
return; return;
} }
$expression = $filterQuery->getExpr()->like($field, $filterQuery->getExpr()->lower($filterQuery->getExpr()->literal('%' . $value . '%'))); $expression = $filterQuery->getExpr()->like($field, $filterQuery->getExpr()->lower($filterQuery->getExpr()->literal('%' . $value . '%')));

View file

@ -107,7 +107,7 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
*/ */
protected function processExtraFields($extraFieldsStrings) protected function processExtraFields($extraFieldsStrings)
{ {
if (!is_array($extraFieldsStrings)) { if (!\is_array($extraFieldsStrings)) {
return []; return [];
} }

View file

@ -85,7 +85,7 @@ class ContentProxy
(new LocaleConstraint()) (new LocaleConstraint())
); );
if (0 === count($errors)) { if (0 === \count($errors)) {
$entry->setLanguage($value); $entry->setLanguage($value);
return; return;
@ -107,7 +107,7 @@ class ContentProxy
(new UrlConstraint()) (new UrlConstraint())
); );
if (0 === count($errors)) { if (0 === \count($errors)) {
$entry->setPreviewPicture($value); $entry->setPreviewPicture($value);
return; return;
@ -212,7 +212,7 @@ class ContentProxy
$entry->setHttpStatus($content['status']); $entry->setHttpStatus($content['status']);
} }
if (!empty($content['authors']) && is_array($content['authors'])) { if (!empty($content['authors']) && \is_array($content['authors'])) {
$entry->setPublishedBy($content['authors']); $entry->setPublishedBy($content['authors']);
} }
@ -233,7 +233,7 @@ class ContentProxy
} }
// if content is an image, define it as a preview too // 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']); $this->updatePreviewPicture($entry, $content['url']);
} }

View file

@ -81,6 +81,6 @@ class CryptoProxy
*/ */
private function mask($value) 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';
} }
} }

View file

@ -85,6 +85,10 @@ class DownloadImages
*/ */
public function processSingleImage($entryId, $imagePath, $url, $relativePath = null) public function processSingleImage($entryId, $imagePath, $url, $relativePath = null)
{ {
if (null === $imagePath) {
return false;
}
if (null === $relativePath) { if (null === $relativePath) {
$relativePath = $this->getRelativePath($entryId); $relativePath = $this->getRelativePath($entryId);
} }
@ -181,7 +185,7 @@ class DownloadImages
* *
* @return array An array of urls * @return array An array of urls
*/ */
protected function getSrcsetUrls(Crawler $imagesCrawler) private function getSrcsetUrls(Crawler $imagesCrawler)
{ {
$urls = []; $urls = [];
$iterator = $imagesCrawler $iterator = $imagesCrawler
@ -189,9 +193,14 @@ class DownloadImages
while ($iterator->valid()) { while ($iterator->valid()) {
$srcsetAttribute = $iterator->current()->getAttribute('srcset'); $srcsetAttribute = $iterator->current()->getAttribute('srcset');
if ('' !== $srcsetAttribute) { if ('' !== $srcsetAttribute) {
$srcset = array_map('trim', explode(',', $srcsetAttribute)); // Couldn't start with " OR ' OR a white space
// Could be one or more white space
// 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);
$srcsetUrls = array_map(function ($src) { $srcsetUrls = array_map(function ($src) {
return explode(' ', $src)[0]; return trim(explode(' ', $src, 2)[0]);
}, $srcset); }, $srcset);
$urls = array_merge($srcsetUrls, $urls); $urls = array_merge($srcsetUrls, $urls);
} }
@ -299,7 +308,7 @@ class DownloadImages
$this->logger->debug('DownloadImages: Checking extension (alternative)', ['ext' => $ext]); $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); $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping: ' . $imagePath);
return false; return false;

View file

@ -45,7 +45,7 @@ class EntriesExport
*/ */
public function setEntries($entries) public function setEntries($entries)
{ {
if (!is_array($entries)) { if (!\is_array($entries)) {
$this->language = $entries->getLanguage(); $this->language = $entries->getLanguage();
$entries = [$entries]; $entries = [$entries];
} }
@ -325,7 +325,7 @@ class EntriesExport
{ {
$delimiter = ';'; $delimiter = ';';
$enclosure = '"'; $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); fputcsv($handle, ['Title', 'URL', 'Content', 'Tags', 'MIME Type', 'Language', 'Creation date'], $delimiter, $enclosure);

View file

@ -31,7 +31,7 @@ class PreparePagerForEntries
$user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
} }
if (null === $user || !is_object($user)) { if (null === $user || !\is_object($user)) {
return; return;
} }

View file

@ -31,7 +31,7 @@ class Redirect
{ {
$user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
if (null === $user || !is_object($user)) { if (null === $user || !\is_object($user)) {
return $url; return $url;
} }

View file

@ -32,7 +32,7 @@ class TagsAssigner
{ {
$tagsEntities = []; $tagsEntities = [];
if (!is_array($tags)) { if (!\is_array($tags)) {
$tags = explode(',', $tags); $tags = explode(',', $tags);
} }
@ -48,7 +48,7 @@ class TagsAssigner
$label = trim(mb_convert_case($label, MB_CASE_LOWER)); $label = trim(mb_convert_case($label, MB_CASE_LOWER));
// avoid empty tag // avoid empty tag
if (0 === strlen($label)) { if (0 === \strlen($label)) {
continue; continue;
} }

View file

@ -36,7 +36,7 @@ class UsernameRssTokenConverter implements ParamConverterInterface
{ {
// If there is no manager, this means that only Doctrine DBAL is configured // If there is no manager, this means that only Doctrine DBAL is configured
// In this case we can do nothing and just return // 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; return false;
} }

View file

@ -21,7 +21,7 @@ class EntryRepository extends EntityRepository
public function getBuilderForAllByUser($userId) public function getBuilderForAllByUser($userId)
{ {
return $this return $this
->getBuilderByUser($userId) ->getSortedQueryBuilderByUser($userId)
; ;
} }
@ -35,7 +35,7 @@ class EntryRepository extends EntityRepository
public function getBuilderForUnreadByUser($userId) public function getBuilderForUnreadByUser($userId)
{ {
return $this return $this
->getBuilderByUser($userId) ->getSortedQueryBuilderByUser($userId)
->andWhere('e.isArchived = false') ->andWhere('e.isArchived = false')
; ;
} }
@ -50,7 +50,7 @@ class EntryRepository extends EntityRepository
public function getBuilderForArchiveByUser($userId) public function getBuilderForArchiveByUser($userId)
{ {
return $this return $this
->getBuilderByUser($userId) ->getSortedQueryBuilderByUser($userId)
->andWhere('e.isArchived = true') ->andWhere('e.isArchived = true')
; ;
} }
@ -65,7 +65,7 @@ class EntryRepository extends EntityRepository
public function getBuilderForStarredByUser($userId) public function getBuilderForStarredByUser($userId)
{ {
return $this return $this
->getBuilderByUser($userId, 'starredAt', 'desc') ->getSortedQueryBuilderByUser($userId, 'starredAt', 'desc')
->andWhere('e.isStarred = true') ->andWhere('e.isStarred = true')
; ;
} }
@ -82,7 +82,7 @@ class EntryRepository extends EntityRepository
public function getBuilderForSearchByUser($userId, $term, $currentRoute) public function getBuilderForSearchByUser($userId, $term, $currentRoute)
{ {
$qb = $this $qb = $this
->getBuilderByUser($userId); ->getSortedQueryBuilderByUser($userId);
if ('starred' === $currentRoute) { if ('starred' === $currentRoute) {
$qb->andWhere('e.isStarred = true'); $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 * @param int $userId
* *
@ -111,8 +111,21 @@ class EntryRepository extends EntityRepository
public function getBuilderForUntaggedByUser($userId) public function getBuilderForUntaggedByUser($userId)
{ {
return $this return $this
->getBuilderByUser($userId) ->sortQueryBuilder($this->getRawBuilderForUntaggedByUser($userId));
->andWhere('size(e.tags) = 0'); }
/**
* 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))); $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) { foreach (explode(',', $tags) as $i => $tag) {
$entryAlias = 'e' . $i; $entryAlias = 'e' . $i;
$tagAlias = 't' . $i; $tagAlias = 't' . $i;
@ -260,7 +273,7 @@ class EntryRepository extends EntityRepository
*/ */
public function removeTag($userId, Tag $tag) public function removeTag($userId, Tag $tag)
{ {
$entries = $this->getBuilderByUser($userId) $entries = $this->getSortedQueryBuilderByUser($userId)
->innerJoin('e.tags', 't') ->innerJoin('e.tags', 't')
->andWhere('t.id = :tagId')->setParameter('tagId', $tag->getId()) ->andWhere('t.id = :tagId')->setParameter('tagId', $tag->getId())
->getQuery() ->getQuery()
@ -296,7 +309,7 @@ class EntryRepository extends EntityRepository
*/ */
public function findAllByTagId($userId, $tagId) public function findAllByTagId($userId, $tagId)
{ {
return $this->getBuilderByUser($userId) return $this->getSortedQueryBuilderByUser($userId)
->innerJoin('e.tags', 't') ->innerJoin('e.tags', 't')
->andWhere('t.id = :tagId')->setParameter('tagId', $tagId) ->andWhere('t.id = :tagId')->setParameter('tagId', $tagId)
->getQuery() ->getQuery()
@ -320,7 +333,7 @@ class EntryRepository extends EntityRepository
->getQuery() ->getQuery()
->getResult(); ->getResult();
if (count($res)) { if (\count($res)) {
return current($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 int $userId
* @param string $sortBy * @param string $sortBy
@ -422,10 +448,23 @@ class EntryRepository extends EntityRepository
* *
* @return QueryBuilder * @return QueryBuilder
*/ */
private function getBuilderByUser($userId, $sortBy = 'createdAt', $direction = 'desc') private function getSortedQueryBuilderByUser($userId, $sortBy = 'createdAt', $direction = 'desc')
{ {
return $this->createQueryBuilder('e') return $this->sortQueryBuilder($this->getQueryBuilderByUser($userId));
->andWhere('e.user = :userId')->setParameter('userId', $userId) }
/**
* 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); ->orderBy(sprintf('e.%s', $sortBy), $direction);
} }
} }

View file

@ -30,7 +30,7 @@ class TagRepository extends EntityRepository
$query->setResultCacheLifetime($cacheLifeTime); $query->setResultCacheLifetime($cacheLifeTime);
} }
return count($query->getArrayResult()); return \count($query->getArrayResult());
} }
/** /**

View file

@ -116,7 +116,7 @@ config:
archived: Remove ALL archived entries archived: Remove ALL archived entries
confirm: Are you really sure? (THIS CAN'T BE UNDONE) confirm: Are you really sure? (THIS CAN'T BE UNDONE)
form_password: form_password:
description: "You can change your password here. Your new password should by at least 8 characters long." description: "You can change your password here. Your new password should be at least 8 characters long."
old_password_label: 'Current password' old_password_label: 'Current password'
new_password_label: 'New password' new_password_label: 'New password'
repeat_new_password_label: 'Repeat new password' repeat_new_password_label: 'Repeat new password'

View file

@ -7,7 +7,7 @@
<meta property="og:title" content="{{ entry.title|e|raw }}" /> <meta property="og:title" content="{{ entry.title|e|raw }}" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:url" content="{{ app.request.uri }}" /> <meta property="og:url" content="{{ app.request.uri }}" />
{% set picturePath = app.request.schemeAndHttpHost ~ asset('wallassets/themes/_global/img/logo-other_themes.png') %} {% set picturePath = app.request.schemeAndHttpHost ~ asset('wallassets/themes/_global/img/logo-wallabag.svg') %}
{% if entry.previewPicture is not null %} {% if entry.previewPicture is not null %}
{% set picturePath = entry.previewPicture %} {% set picturePath = entry.previewPicture %}
{% endif %} {% endif %}

View file

@ -11,7 +11,7 @@
<main class="valign-wrapper"> <main class="valign-wrapper">
<div class="valign row"> <div class="valign row">
<div class="card sw"> <div class="card sw">
<div class="center"><img src="{{ asset('wallassets/themes/_global/img/logo-other_themes.png') }}" alt="wallabag logo" /></div> <div class="center"><img src="{{ asset('wallassets/themes/_global/img/logo-wallabag.svg') }}" alt="wallabag logo" class="typo-logo" /></div>
<div class="card-content"> <div class="card-content">
<div class="row"> <div class="row">
<h5>{{ status_code }}: {{ status_text }}</h5> <h5>{{ status_code }}: {{ status_text }}</h5>

View file

@ -29,7 +29,7 @@
{% block logo %} {% block logo %}
<li class="logo border-bottom"> <li class="logo border-bottom">
<a title="{{ 'menu.left.back_to_unread'|trans }}" href="{{ path('unread') }}"> <a title="{{ 'menu.left.back_to_unread'|trans }}" href="{{ path('unread') }}">
<img src="{{ asset('wallassets/themes/_global/img/logo-square.png') }}" alt="wallabag logo" /> <img src="{{ asset('wallassets/themes/_global/img/logo-square.svg') }}" alt="wallabag logo" />
</a> </a>
</li> </li>
{% endblock %} {% endblock %}

View file

@ -29,6 +29,6 @@ class Utils
*/ */
public static function getReadingTime($text) 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);
} }
} }

View file

@ -64,7 +64,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
{ {
$user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
if (null === $user || !is_object($user)) { if (null === $user || !\is_object($user)) {
return 0; return 0;
} }
@ -96,7 +96,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
$query->useResultCache(true); $query->useResultCache(true);
$query->setResultCacheLifetime($this->lifeTime); $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; $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
if (null === $user || !is_object($user)) { if (null === $user || !\is_object($user)) {
return 0; return 0;
} }
@ -124,7 +124,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
{ {
$user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
if (null === $user || !is_object($user)) { if (null === $user || !\is_object($user)) {
return 0; return 0;
} }
@ -137,7 +137,7 @@ class WallabagExtension extends \Twig_Extension implements \Twig_Extension_Globa
$query->useResultCache(true); $query->useResultCache(true);
$query->setResultCacheLifetime($this->lifeTime); $query->setResultCacheLifetime($this->lifeTime);
$nbArchives = count($query->getArrayResult()); $nbArchives = \count($query->getArrayResult());
$interval = $user->getCreatedAt()->diff(new \DateTime('now')); $interval = $user->getCreatedAt()->diff(new \DateTime('now'));
$nbDays = (int) $interval->format('%a') ?: 1; $nbDays = (int) $interval->format('%a') ?: 1;

View file

@ -43,7 +43,7 @@ class ImportCommand extends ContainerAwareCommand
$user = $em->getRepository('WallabagUserBundle:User')->findOneByUsername($input->getArgument('username')); $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'))); throw new Exception(sprintf('User "%s" not found', $input->getArgument('username')));
} }

View file

@ -30,7 +30,7 @@ abstract class BrowserController extends Controller
$markAsRead = $form->get('mark_as_read')->getData(); $markAsRead = $form->get('mark_as_read')->getData();
$name = $this->getUser()->getId() . '.json'; $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 $res = $wallabag
->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name) ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
->setMarkAsRead($markAsRead) ->setMarkAsRead($markAsRead)

View file

@ -31,7 +31,7 @@ class InstapaperController extends Controller
$markAsRead = $form->get('mark_as_read')->getData(); $markAsRead = $form->get('mark_as_read')->getData();
$name = 'instapaper_' . $this->getUser()->getId() . '.csv'; $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 $res = $instapaper
->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name) ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
->setMarkAsRead($markAsRead) ->setMarkAsRead($markAsRead)

View file

@ -31,7 +31,7 @@ class PinboardController extends Controller
$markAsRead = $form->get('mark_as_read')->getData(); $markAsRead = $form->get('mark_as_read')->getData();
$name = 'pinboard_' . $this->getUser()->getId() . '.json'; $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 $res = $pinboard
->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name) ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
->setMarkAsRead($markAsRead) ->setMarkAsRead($markAsRead)

View file

@ -31,7 +31,7 @@ class ReadabilityController extends Controller
$markAsRead = $form->get('mark_as_read')->getData(); $markAsRead = $form->get('mark_as_read')->getData();
$name = 'readability_' . $this->getUser()->getId() . '.json'; $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 $res = $readability
->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name) ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
->setMarkAsRead($markAsRead) ->setMarkAsRead($markAsRead)

View file

@ -33,7 +33,7 @@ abstract class WallabagController extends Controller
$markAsRead = $form->get('mark_as_read')->getData(); $markAsRead = $form->get('mark_as_read')->getData();
$name = $this->getUser()->getId() . '.json'; $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 $res = $wallabag
->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name) ->setFilepath($this->getParameter('wallabag_import.resource_dir') . '/' . $name)
->setMarkAsRead($markAsRead) ->setMarkAsRead($markAsRead)

View file

@ -77,7 +77,7 @@ abstract class BrowserImport extends AbstractImport
*/ */
public function parseEntry(array $importedEntry) 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) { if ($this->producer) {
$this->parseEntriesForProducer($importedEntry); $this->parseEntriesForProducer($importedEntry);

View file

@ -62,7 +62,7 @@ class InstapaperImport extends AbstractImport
} }
$entries = []; $entries = [];
$handle = fopen($this->filepath, 'r'); $handle = fopen($this->filepath, 'rb');
while (false !== ($data = fgetcsv($handle, 10240))) { while (false !== ($data = fgetcsv($handle, 10240))) {
if ('URL' === $data[0]) { if ('URL' === $data[0]) {
continue; continue;
@ -72,7 +72,7 @@ class InstapaperImport extends AbstractImport
// BUT it can also be the status (since status = folder in Instapaper) // BUT it can also be the status (since status = folder in Instapaper)
// and we don't want archive, unread & starred to become a tag // and we don't want archive, unread & starred to become a tag
$tags = null; $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]]; $tags = [$data[3]];
} }

View file

@ -149,7 +149,7 @@ class PocketImport extends AbstractImport
// - first call get 5k offset 0 // - first call get 5k offset 0
// - second call get 5k offset 5k // - second call get 5k offset 5k
// - and so on // - and so on
if (self::NB_ELEMENTS === count($entries['list'])) { if (self::NB_ELEMENTS === \count($entries['list'])) {
++$run; ++$run;
return $this->import(self::NB_ELEMENTS * $run); return $this->import(self::NB_ELEMENTS * $run);

View 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 // 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 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['title'] = $this->fetchingErrorMessageTitle;
$data['html'] = $this->fetchingErrorMessage; $data['html'] = $this->fetchingErrorMessage;
} }

View file

@ -16,7 +16,7 @@
<div class="input-field col s12"> <div class="input-field col s12">
<label for="username">{{ 'security.login.username'|trans }}</label> <label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" /> <input type="text" id="username" name="_username" value="{{ last_username }}" autofocus />
</div> </div>
<div class="input-field col s12"> <div class="input-field col s12">

View file

@ -11,7 +11,7 @@
<main class="valign-wrapper"> <main class="valign-wrapper">
<div class="valign row"> <div class="valign row">
<div class="card sw"> <div class="card sw">
<div class="center"><img src="{{ asset('wallassets/themes/_global/img/logo-other_themes.png') }}" alt="wallabag logo" /></div> <div class="center"><img src="{{ asset('wallassets/themes/_global/img/logo-wallabag.svg') }}" alt="wallabag logo" class="typo-logo" /></div>
{% block fos_user_content %} {% block fos_user_content %}
{% endblock fos_user_content %} {% endblock fos_user_content %}
</div> </div>

View file

@ -28,7 +28,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase
$this->assertSame(200, $client->getResponse()->getStatusCode()); $this->assertSame(200, $client->getResponse()->getStatusCode());
$newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); $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->assertGreaterThan(1, $alert = $crawler->filter('.settings ul li strong')->extract(['_text']));
$this->assertContains('My app', $alert[0]); $this->assertContains('My app', $alert[0]);
@ -65,7 +65,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase
$crawler = $client->request('GET', '/developer'); $crawler = $client->request('GET', '/developer');
$this->assertSame(200, $client->getResponse()->getStatusCode()); $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() public function testDeveloperHowto()

View file

@ -28,7 +28,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$this->assertSame($entry->getTitle(), $content['title']); $this->assertSame($entry->getTitle(), $content['title']);
$this->assertSame($entry->getUrl(), $content['url']); $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->getUserName(), $content['user_name']);
$this->assertSame($entry->getUserEmail(), $content['user_email']); $this->assertSame($entry->getUserEmail(), $content['user_email']);
$this->assertSame($entry->getUserId(), $content['user_id']); $this->assertSame($entry->getUserId(), $content['user_id']);
@ -127,7 +127,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertNotEmpty($content['_embedded']['items']); $this->assertNotEmpty($content['_embedded']['items']);
$this->assertGreaterThanOrEqual(1, $content['total']); $this->assertGreaterThanOrEqual(1, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -154,7 +154,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertArrayHasKey('items', $content['_embedded']); $this->assertArrayHasKey('items', $content['_embedded']);
$this->assertGreaterThanOrEqual(0, $content['total']); $this->assertGreaterThanOrEqual(0, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -206,7 +206,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertArrayHasKey('items', $content['_embedded']); $this->assertArrayHasKey('items', $content['_embedded']);
$this->assertGreaterThanOrEqual(1, $content['total']); $this->assertGreaterThanOrEqual(1, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -250,7 +250,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertNotEmpty($content['_embedded']['items']); $this->assertNotEmpty($content['_embedded']['items']);
$this->assertGreaterThanOrEqual(1, $content['total']); $this->assertGreaterThanOrEqual(1, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -278,7 +278,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertNotEmpty($content['_embedded']['items']); $this->assertNotEmpty($content['_embedded']['items']);
$this->assertGreaterThanOrEqual(1, $content['total']); $this->assertGreaterThanOrEqual(1, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -305,7 +305,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertNotEmpty($content['_embedded']['items']); $this->assertNotEmpty($content['_embedded']['items']);
$this->assertGreaterThanOrEqual(1, $content['total']); $this->assertGreaterThanOrEqual(1, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -342,7 +342,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertNotEmpty($content['_embedded']['items']); $this->assertNotEmpty($content['_embedded']['items']);
$this->assertGreaterThanOrEqual(1, $content['total']); $this->assertGreaterThanOrEqual(1, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -370,7 +370,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, count($content)); $this->assertGreaterThanOrEqual(1, \count($content));
$this->assertEmpty($content['_embedded']['items']); $this->assertEmpty($content['_embedded']['items']);
$this->assertSame(0, $content['total']); $this->assertSame(0, $content['total']);
$this->assertSame(1, $content['page']); $this->assertSame(1, $content['page']);
@ -608,7 +608,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$this->assertSame($entry->getId(), $content['id']); $this->assertSame($entry->getId(), $content['id']);
$this->assertSame($entry->getUrl(), $content['url']); $this->assertSame($entry->getUrl(), $content['url']);
$this->assertSame('New awesome title', $content['title']); $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(1, $content['user_id']);
$this->assertSame('de_AT', $content['language']); $this->assertSame('de_AT', $content['language']);
$this->assertSame('http://preview.io/picture.jpg', $content['preview_picture']); $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->getId(), $content['id']);
$this->assertSame($entry->getUrl(), $content['url']); $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->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($previousContent, $content['content'], 'Ensure content has not moved');
$this->assertSame($previousLanguage, $content['language'], 'Ensure language 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.'); $this->markTestSkipped('No content found in db.');
} }
$nbTags = count($entry->getTags()); $nbTags = \count($entry->getTags());
$newTags = 'tag1,tag2,tag3'; $newTags = 'tag1,tag2,tag3';
@ -783,7 +783,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
$content = json_decode($this->client->getResponse()->getContent(), true); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('tags', $content); $this->assertArrayHasKey('tags', $content);
$this->assertSame($nbTags + 3, count($content['tags'])); $this->assertSame($nbTags + 3, \count($content['tags']));
$entryDB = $this->client->getContainer() $entryDB = $this->client->getContainer()
->get('doctrine.orm.entity_manager') ->get('doctrine.orm.entity_manager')
@ -813,7 +813,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
} }
// hydrate the tags relations // hydrate the tags relations
$nbTags = count($entry->getTags()); $nbTags = \count($entry->getTags());
$tag = $entry->getTags()[0]; $tag = $entry->getTags()[0];
$this->client->request('DELETE', '/api/entries/' . $entry->getId() . '/tags/' . $tag->getId() . '.json'); $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); $content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('tags', $content); $this->assertArrayHasKey('tags', $content);
$this->assertSame($nbTags - 1, count($content['tags'])); $this->assertSame($nbTags - 1, \count($content['tags']));
} }
public function testSaveIsArchivedAfterPost() public function testSaveIsArchivedAfterPost()

View file

@ -524,7 +524,7 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertGreaterThan(1, $title = $crawler->filter('div[id=article] h1')->extract(['_text'])); $this->assertGreaterThan(1, $title = $crawler->filter('div[id=article] h1')->extract(['_text']));
$this->assertContains('My updated title hehe :)', $title[0]); $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])); $this->assertNotContains('example.io', trim($stats[0]));
} }
@ -1325,10 +1325,6 @@ class EntryControllerTest extends WallabagCoreTestCase
'http://www.hao123.com/shequ?__noscript__-=1', 'http://www.hao123.com/shequ?__noscript__-=1',
'zh_CN', 'zh_CN',
], ],
'de_AT' => [
'https://buy.garmin.com/de-AT/AT/catalog/product/compareResult.ep?compareProduct=112885&compareProduct=36728',
'de_AT',
],
'ru_RU' => [ 'ru_RU' => [
'http://netler.ru/ikt/windows-error-reporting.htm', 'http://netler.ru/ikt/windows-error-reporting.htm',
'ru_RU', 'ru_RU',

View file

@ -180,7 +180,7 @@ class ExportControllerTest extends WallabagCoreTestCase
$this->assertGreaterThan(1, $csv); $this->assertGreaterThan(1, $csv);
// +1 for title line // +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->assertSame('Title;URL;Content;Tags;"MIME Type";Language;"Creation date"', $csv[0]);
$this->assertContains($contentInDB[0]['title'], $csv[1]); $this->assertContains($contentInDB[0]['title'], $csv[1]);
$this->assertContains($contentInDB[0]['url'], $csv[1]); $this->assertContains($contentInDB[0]['url'], $csv[1]);
@ -272,7 +272,7 @@ class ExportControllerTest extends WallabagCoreTestCase
$content = new \SimpleXMLElement($client->getResponse()->getContent()); $content = new \SimpleXMLElement($client->getResponse()->getContent());
$this->assertGreaterThan(0, $content->count()); $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('id', (string) $content->entry[0]->id);
$this->assertNotEmpty('title', (string) $content->entry[0]->title); $this->assertNotEmpty('title', (string) $content->entry[0]->title);
$this->assertNotEmpty('url', (string) $content->entry[0]->url); $this->assertNotEmpty('url', (string) $content->entry[0]->url);

View file

@ -98,7 +98,7 @@ class TagControllerTest extends WallabagCoreTestCase
$tags[$key] = $tag->getLabel(); $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('foo2', $tags, true), 'Tag foo2 is assigned to the entry');
$this->assertNotFalse(array_search('bar2', $tags, true), 'Tag bar2 is assigned to the entry'); $this->assertNotFalse(array_search('bar2', $tags, true), 'Tag bar2 is assigned to the entry');
} }

View file

@ -204,4 +204,52 @@ class DownloadImagesTest extends TestCase
$this->assertNotContains('http://piketty.blog.lemonde.fr/', $res, 'Image srcset attribute were not replaced'); $this->assertNotContains('http://piketty.blog.lemonde.fr/', $res, 'Image srcset attribute were not replaced');
} }
public function testProcessImageWithTrickySrcset()
{
$client = new Client();
$mock = new Mock([
new Response(200, ['content-type' => 'image/jpeg'], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/image-no-content-type.jpg'))),
new Response(200, ['content-type' => 'image/jpeg'], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/image-no-content-type.jpg'))),
new Response(200, ['content-type' => 'image/jpeg'], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/image-no-content-type.jpg'))),
]);
$client->getEmitter()->attach($mock);
$logHandler = new TestHandler();
$logger = new Logger('test', [$logHandler]);
$download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger);
$res = $download->processHtml(123, '<figure id="post-257260" class="align-none media-257260"><img src="https://cdn.css-tricks.com/wp-content/uploads/2017/08/the-critical-request.png" srcset="https://res.cloudinary.com/css-tricks/image/upload/c_scale,w_1000,f_auto,q_auto/v1501594717/the-critical-request_bqdfaa.png 1000w, https://res.cloudinary.com/css-tricks/image/upload/c_scale,w_200,f_auto,q_auto/v1501594717/the-critical-request_bqdfaa.png 200w" sizes="(min-width: 1850px) calc( (100vw - 555px) / 3 )
(min-width: 1251px) calc( (100vw - 530px) / 2 )
(min-width: 1086px) calc(100vw - 480px)
(min-width: 626px) calc(100vw - 335px)
calc(100vw - 30px)" alt="" /></figure>', 'https://css-tricks.com/the-critical-request/');
$this->assertNotContains('f_auto,q_auto', $res, 'Image srcset attribute were not replaced');
}
public function testProcessImageWithNullPath()
{
$client = new Client();
$mock = new Mock([
new Response(200, ['content-type' => null], Stream::factory(file_get_contents(__DIR__ . '/../fixtures/image-no-content-type.jpg'))),
]);
$client->getEmitter()->attach($mock);
$logHandler = new TestHandler();
$logger = new Logger('test', [$logHandler]);
$download = new DownloadImages($client, sys_get_temp_dir() . '/wallabag_test', 'http://wallabag.io/', $logger);
$res = $download->processSingleImage(
123,
null,
'https://framablog.org/2018/06/30/engagement-atypique/'
);
$this->assertFalse($res);
}
} }

View file

@ -121,7 +121,7 @@ class ChromeControllerTest extends WallabagCoreTestCase
$this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for http://www.usinenouvelle.com is ok'); $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->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(); $createdAt = $content->getCreatedAt();
$this->assertSame('2011', $createdAt->format('Y')); $this->assertSame('2011', $createdAt->format('Y'));

View file

@ -122,20 +122,20 @@ class FirefoxControllerTest extends WallabagCoreTestCase
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for http://lexpansion.lexpress.fr is ok'); $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->getPreviewPicture(), 'Preview picture for http://lexpansion.lexpress.fr is ok');
$this->assertNotEmpty($content->getLanguage(), 'Language 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() $content = $client->getContainer()
->get('doctrine.orm.entity_manager') ->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry') ->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId( ->findByUrlAndUserId(
'https://stackoverflow.com/questions/15017163/parser-for-exported-bookmarks-html-file-of-google-chrome-and-mozilla-in-java', 'https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html',
$this->getLoggedInUserId() $this->getLoggedInUserId()
); );
$this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://stackoverflow.com is ok'); $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.lemonde.fr is ok');
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://stackoverflow.com is ok'); $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.lemonde.fr is ok');
$this->assertEmpty($content->getLanguage(), 'Language for https://stackoverflow.com is ok'); $this->assertNotEmpty($content->getLanguage(), 'Language for https://www.lemonde.fr is ok');
$createdAt = $content->getCreatedAt(); $createdAt = $content->getCreatedAt();
$this->assertSame('2013', $createdAt->format('Y')); $this->assertSame('2013', $createdAt->format('Y'));

View file

@ -122,7 +122,7 @@ class InstapaperControllerTest extends WallabagCoreTestCase
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture 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->assertNotEmpty($content->getLanguage(), 'Language for http://www.liberation.fr is ok');
$this->assertContains('foot', $content->getTags(), 'It includes the "foot" tag'); $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()); $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$content = $client->getContainer() $content = $client->getContainer()
@ -136,7 +136,7 @@ class InstapaperControllerTest extends WallabagCoreTestCase
$this->assertContains('foot', $content->getTags()); $this->assertContains('foot', $content->getTags());
$this->assertContains('test_tag', $content->getTags()); $this->assertContains('test_tag', $content->getTags());
$this->assertSame(2, count($content->getTags())); $this->assertSame(2, \count($content->getTags()));
} }
public function testImportInstapaperWithFileAndMarkAllAsRead() public function testImportInstapaperWithFileAndMarkAllAsRead()

View file

@ -127,7 +127,7 @@ class PinboardControllerTest extends WallabagCoreTestCase
$this->assertContains('foot', $tags, 'It includes the "foot" tag'); $this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertContains('varnish', $tags, 'It includes the "varnish" tag'); $this->assertContains('varnish', $tags, 'It includes the "varnish" tag');
$this->assertContains('php', $tags, 'It includes the "php" 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->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$this->assertSame('2016-10-26', $content->getCreatedAt()->format('Y-m-d')); $this->assertSame('2016-10-26', $content->getCreatedAt()->format('Y-m-d'));

View file

@ -125,7 +125,7 @@ class ReadabilityControllerTest extends WallabagCoreTestCase
$tags = $content->getTags(); $tags = $content->getTags();
$this->assertContains('foot', $tags, 'It includes the "foot" tag'); $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->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d')); $this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d'));

View file

@ -127,7 +127,7 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase
$tags = $content->getTags(); $tags = $content->getTags();
$this->assertContains('foot', $tags, 'It includes the "foot" tag'); $this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertContains('framabag', $tags, 'It includes the "framabag" 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()); $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
} }

View file

@ -128,7 +128,7 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase
$tags = $content->getTags(); $tags = $content->getTags();
$this->assertContains('foot', $tags, 'It includes the "foot" tag'); $this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertSame(1, count($tags)); $this->assertSame(1, \count($tags));
$content = $client->getContainer() $content = $client->getContainer()
->get('doctrine.orm.entity_manager') ->get('doctrine.orm.entity_manager')
@ -147,7 +147,7 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase
$this->assertContains('foot', $tags, 'It includes the "foot" tag'); $this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertContains('mediapart', $tags, 'It includes the "mediapart" tag'); $this->assertContains('mediapart', $tags, 'It includes the "mediapart" tag');
$this->assertContains('blog', $tags, 'It includes the "blog" 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->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d')); $this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d'));

View file

@ -39,13 +39,13 @@
}, },
{ {
"guid": "E385l9vZ_LVn", "guid": "E385l9vZ_LVn",
"title": "Parser for Exported Bookmarks HTML file of Google Chrome and Mozilla in Java", "title": "Le journaliste et cinéaste Claude Lanzmann est mort",
"index": 1, "index": 1,
"dateAdded": 1388166091544000, "dateAdded": 1388166091544000,
"lastModified": 1388166091545000, "lastModified": 1388166091545000,
"id": 5, "id": 5,
"type": "text/x-moz-place", "type": "text/x-moz-place",
"uri": "http://stackoverflow.com/questions/15017163/parser-for-exported-bookmarks-html-file-of-google-chrome-and-mozilla-in-java" "uri": "https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html"
} }
] ]
}, },

View file

@ -13,7 +13,7 @@ final class CountableMemorySpool extends \Swift_MemorySpool implements \Countabl
{ {
public function count() public function count()
{ {
return count($this->messages); return \count($this->messages);
} }
public function getMessages() public function getMessages()

View file

@ -389,7 +389,7 @@ class SymfonyRequirements extends RequirementCollection
{ {
/* mandatory requirements follow */ /* mandatory requirements follow */
$installedPhpVersion = phpversion(); $installedPhpVersion = PHP_VERSION;
$requiredPhpVersion = $this->getPhpRequiredVersion(); $requiredPhpVersion = $this->getPhpRequiredVersion();
$this->addRecommendation( $this->addRecommendation(
@ -448,15 +448,8 @@ class SymfonyRequirements extends RequirementCollection
} }
if (false !== $requiredPhpVersion && version_compare($installedPhpVersion, $requiredPhpVersion, '>=')) { 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( $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()), 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>.' '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).' '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->addRecommendation(
$this->getRealpathCacheSize() >= 5 * 1024 * 1024, $this->getRealpathCacheSize() >= 5 * 1024 * 1024,
'realpath_cache_size should be at least 5M in php.ini', 'realpath_cache_size should be at least 5M in php.ini',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,video{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-spacing:0}body{background-color:#fff;color:#444;font-family:Georgia;line-height:1.7;-ms-content-zooming:none;margin-bottom:64px}h1,h2,h3,h4,h5,h6{font-weight:600;margin:.2em 0}article h1,article h2,article h3,article h4,article h5,article h6{text-align:left;line-height:1.3}h1{font-size:1.4em}h2{font-size:1.3em}h3,h4{font-size:1.2em}h5,h6{font-size:1.1em}p{margin-bottom:.75em}b,strong{font-weight:700}em,i{font-style:italic}a{color:#444;text-decoration:underline}a:active,a:hover{outline:0}dl,ol,p,ul{margin:0 0 1.75em}ol,ul{padding-left:1.25em}li{padding-bottom:.2em;line-height:1.6}li li:last-child,li p:last-child{margin-bottom:-.2em}ol li:last-child,ul li:last-child{padding-bottom:0}mark{padding:0 .2em}mark a{text-decoration:none}blockquote{font-style:italic;border-left:.25em solid #000;margin-left:-20px;padding-left:17px;margin-bottom:.5em;margin-top:.5em}blockquote cite{text-transform:uppercase;font-size:.8em;font-style:normal}blockquote cite:before{content:"\2014";margin-right:.5em}img{display:block;height:auto;margin-bottom:.5em;max-width:100%}figure{margin:0}figure figcaption{display:block;margin-top:.3em;font-style:italic;font-size:.8em}button{display:none!important}hr{display:block;height:1px;border:solid #666;border-width:1px 0 0;margin:1.6em 0;padding:0}small{font-size:.7em}dl{margin:1.6em 0}dl dt{float:left;width:11.25em;overflow:hidden;clear:left;text-align:right;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;font-weight:700}dl dd,dl dt{margin-bottom:1em}dl dd{margin-left:12.5em}pre{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:4em 0;border:.0625em solid #efefef;width:100%;padding:1em;font-family:Consolas,monospace;white-space:pre;overflow:auto}pre code{line-height:1.6em;white-space:pre-wrap;background:transparent;border:none;padding:0;vertical-align:inherit}code,pre code{font-size:.8em}code{padding:.125em .375em;margin:0 .2em;font-family:Consolas,monospace;white-space:pre;border:1px solid #d3d3d3;overflow:auto}audio,video{max-width:43.75em}::selection,mark{background:#666;color:#fff}table{border-collapse:collapse;margin-bottom:2em;width:100%}td,th{padding:.25em;text-align:left}thead tr{text-transform:uppercase;font-size:.85em;letter-spacing:1px;font-family:Segoe UI,sans-serif;font-weight:600}tbody tr:nth-child(odd){background:rgba(0,0,0,.1)}tbody{border:solid #999;border-width:1px 0}figure{text-align:center}figure>*{margin:0 auto}header{text-align:center}.shared-by{margin-bottom:1em}@media (max-width:719px){article,header>:not(.preview){padding:0 1em}}@media (min-width:720px){blockquote{margin-left:-1.4375em;padding-left:1.25em}header{margin-top:32px}.block{margin-left:auto;margin-right:auto;max-width:43.75em;padding:0 1.25em}} a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,video{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-spacing:0}body{background-color:#fff;color:#444;font-family:Georgia;line-height:1.7;-ms-content-zooming:none;margin-bottom:64px}h1,h2,h3,h4,h5,h6{font-weight:600;margin:.2em 0}article h1,article h2,article h3,article h4,article h5,article h6{text-align:left;line-height:1.3}h1{font-size:1.4em}h2{font-size:1.3em}h3,h4{font-size:1.2em}h5,h6{font-size:1.1em}p{margin-bottom:.75em}b,strong{font-weight:700}em,i{font-style:italic}a{color:#444;text-decoration:underline}a:active,a:hover{outline:0}dl,ol,p,ul{margin:0 0 1.75em}ol,ul{padding-left:1.25em}li{padding-bottom:.2em;line-height:1.6}li li:last-child,li p:last-child{margin-bottom:-.2em}ol li:last-child,ul li:last-child{padding-bottom:0}iframe,video{max-width:100%;height:auto}mark{padding:0 .2em}mark a{text-decoration:none}blockquote{font-style:italic;border-left:.25em solid #000;margin-left:-20px;padding-left:17px;margin-bottom:.5em;margin-top:.5em}blockquote cite{text-transform:uppercase;font-size:.8em;font-style:normal}blockquote cite:before{content:"\2014";margin-right:.5em}img{display:block;height:auto;margin-bottom:.5em;max-width:100%}figure{margin:0}figure figcaption{display:block;margin-top:.3em;font-style:italic;font-size:.8em}button{display:none!important}hr{display:block;height:1px;border:solid #666;border-width:1px 0 0;margin:1.6em 0;padding:0}small{font-size:.7em}dl{margin:1.6em 0}dl dt{float:left;width:11.25em;overflow:hidden;clear:left;text-align:right;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;font-weight:700}dl dd,dl dt{margin-bottom:1em}dl dd{margin-left:12.5em}pre{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:4em 0;border:.0625em solid #efefef;width:100%;padding:1em;font-family:Consolas,monospace;white-space:pre;overflow:auto}pre code{line-height:1.6em;white-space:pre-wrap;background:transparent;border:none;padding:0;vertical-align:inherit}code,pre code{font-size:.8em}code{padding:.125em .375em;margin:0 .2em;font-family:Consolas,monospace;white-space:pre;border:1px solid #d3d3d3;overflow:auto}audio,video{max-width:43.75em}::selection,mark{background:#666;color:#fff}table{border-collapse:collapse;margin-bottom:2em;width:100%}td,th{padding:.25em;text-align:left}thead tr{text-transform:uppercase;font-size:.85em;letter-spacing:1px;font-family:Segoe UI,sans-serif;font-weight:600}tbody tr:nth-child(odd){background:rgba(0,0,0,.1)}tbody{border:solid #999;border-width:1px 0}figure{text-align:center}figure>*{margin:0 auto}header{text-align:center}.shared-by{margin-bottom:1em}@media (max-width:719px){article,header>:not(.preview){padding:0 1em}}@media (min-width:720px){blockquote{margin-left:-1.4375em;padding-left:1.25em}header{margin-top:32px}.block{margin-left:auto;margin-right:auto;max-width:43.75em;padding:0 1.25em}}
/*# sourceMappingURL=public.css.map*/ /*# sourceMappingURL=public.css.map*/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path fill="none" d="M0 0h200v200H0z"/><path d="M75.899 72.438c1.597-.981 10.207-5.556 24.098.178 14.289 5.897 23.154.776 24.253.079-3.454-5.678-7.562-10.62-12.104-13.943.303-.083.612-.167.939-.263 6.023-1.742 7.553-6.842 7.875-11.21.364-4.954.616-5.03 1.692-9.487 1.032-4.281-.119-5.137-1.181-4.273-.572.465-5.552 1.616-8.505 3.919-4.768 3.72-7.707 10.794-9.039 14.706-.025.06-.205.604-.265.792-.621 1.498-1.857 1.494-1.857 1.494v.001c-.6-.065-1.202-.1-1.809-.1-.54 0-1.079.029-1.616.081-.012.002-.019 0-.031.001-1.581.233-2.45-1.697-2.632-2.157-1.847-5.304-6.816-15.763-17.984-18.577 0 0-2.028-1.554-1.41 1.074.588 2.511 1.804 5.049 1.534 8.741-.124 1.704-1.181 10.442 6.85 14.99.763.432 1.441.795 2.051 1.101-4.042 3.235-7.716 7.74-10.859 12.853zM128.626 152.353c-9.842-6.098-13.153-8.242-12.946-10.575 0 0 .002-.379.099-.957.239-1.236.995-3.348 3.407-4.552.079-.039.146-.084.208-.129 7.668-4.45 13.27-11.614 15.246-20.56-1.99 4.941-16.735 8.78-34.645 8.78-17.903 0-32.651-3.839-34.641-8.78.442 2.008 1.073 3.923 1.864 5.742.666 3.745 1.562 12.563-2.673 20.282-3.731 6.8-22.15 16.069-49.485 10.748 0 0-1.096-.766-1.428-.136-.491.932 1.517 1.685 3.583 2.229 19.031 5.04 47.756 2.989 56.777-4.443 4.116-3.388 5.704-7.953 6.107-12.865l.003.008s.11-1.287 1.719-.32c.461.277 2.125 1.36 2.39 2.585.232 1.743.248 3.883-.652 5.382-1.287 2.144-1.301 2.452.393 3.662 1.04.742 5.287 3.864 11.198 7.415.015.01.023.019.038.027 1.25.753 2.987 2.597 2.987 2.597 2.662 3.079 8.452 9.275 10.972 8.108 1.19-.551-.051-3.032-.051-3.032s1.98 2.571 3.043 1.694c.809-.668-.473-3.229-.473-3.229s1.729 1.499 2.757.944c1.258-.679-.187-4.614-10.079-10.627-9.896-6.018-12.578-6.94-12.814-9.626 0 0-.004-.135.004-.366.077-.593.414-1.847 1.852-1.712 2.141.346 4.348.531 6.608.531 2.587 0 5.107-.237 7.536-.69l.001.003s.127-.025.164-.031c.284-.036.838-.018.84.671-.09.873-.331 1.751-.845 2.519-1.447 2.168-.972 2.466.54 3.859.933.859 5.211 4.622 11.07 8.264.012.009.017.016.031.023 1.249.752 3.41 2.816 3.41 2.816v-.001c2.428 2.466 6.894 6.596 9.327 6.347 1.646-.168.306-3.002.306-3.002s2.078 2.006 3.099 1.416c1.142-.659-.474-2.755-.474-2.755s1.338.708 2.283.473c.948-.236 1.185-2.644-8.656-8.737z"/><path d="M117.631 83.452c-1.181 0-2.161.355-2.912 1.057-.76.71-1.144 1.531-1.144 2.438v16.056c0 2.154-.382 3.742-1.135 4.721-.728.946-1.892 1.406-3.556 1.406-1.703 0-2.863-.457-3.549-1.396-.716-.979-1.078-2.571-1.078-4.731V86.884c0-1.098-.5-1.996-1.448-2.596-1.289-.812-2.57-1.105-4.129-.587-.476.159-.924.366-1.333.615-.435.265-.802.597-1.093.985-.322.432-.486.901-.486 1.396v16.307c0 2.158-.363 3.75-1.079 4.73-.688.939-1.849 1.396-3.548 1.396-1.705 0-2.877-.459-3.584-1.401-.734-.979-1.107-2.57-1.107-4.726V86.947c0-.908-.384-1.728-1.145-2.438-.751-.702-1.751-1.057-2.973-1.057-1.258 0-2.296.352-3.085 1.045-.811.71-1.222 1.535-1.222 2.45v15.806c0 1.988.194 3.869.575 5.588.393 1.758 1.077 3.3 2.035 4.586.968 1.299 2.282 2.323 3.906 3.05 1.607.716 3.617 1.079 5.975 1.079 2.457 0 4.515-.455 6.115-1.354 1.342-.754 2.473-1.744 3.371-2.951.866 1.207 1.971 2.197 3.294 2.95 1.58.899 3.669 1.354 6.211 1.354 2.357 0 4.359-.364 5.947-1.081 1.601-.726 2.902-1.751 3.872-3.048.96-1.29 1.645-2.833 2.034-4.586.381-1.719.575-3.6.575-5.588V86.947c0-.911-.398-1.733-1.184-2.445-.767-.697-1.818-1.05-3.12-1.05z"/></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB