Compare commits

...

18 Commits
2.6.7 ... 2.6.8

Author SHA1 Message Date
3d26ddde88 Merge pull request #7143 from wallabag/release/2.6.8
Prepare 2.6.8 release
2024-01-03 08:24:57 +01:00
c8f036ad0f Prepare 2.6.8 release 2024-01-03 07:31:07 +01:00
5e89fc2606 Merge pull request #7140 from yguedidi/remove-session-based-redirection
Remove session-based redirection
2024-01-02 23:39:10 +01:00
9bef459882 Make Redirect helper supports only absolute path reference URLs 2023-12-28 21:48:48 +01:00
7ebc96f3b9 Remove session-based redirection 2023-12-28 21:42:26 +01:00
f4493f7472 Remove support for fallback in Redirect helper 2023-12-28 21:42:12 +01:00
ffec47bd88 Use Redirect helper in ConfigController::changeViewModeAction 2023-12-28 21:26:30 +01:00
4a8fb78c7c Merge pull request #7141 from yguedidi/fix-docker-setup
Fix docker setup
2023-12-27 19:24:21 +01:00
967f8fa495 Fix docker setup 2023-12-27 19:18:54 +01:00
3a7e597ffc Merge pull request #7142 from yguedidi/make-database-dependent-commands-lazy
Make database dependent commands lazy
2023-12-27 19:08:18 +01:00
9927a06cab Make database dependent commands lazy 2023-12-26 21:29:00 +01:00
d6c401423f Merge pull request #7133 from Simounet/fix/dark-mode-disabled-url-2.6 2023-12-22 20:43:28 +01:00
6725228ed5 Assets generation 2023-12-22 15:29:06 +01:00
165973d834 Fix add tags input dark mode 2023-12-22 15:01:23 +01:00
e018daf2fa Fix disabled URL edit dark mode 2023-12-22 15:01:23 +01:00
902edbfeb6 Merge pull request #7134 from wallabag/fix/2.6-update-deps
Update deps & Node 20
2023-12-22 14:59:13 +01:00
75f6f53d25 Update GitHub Actions 2023-12-22 14:45:23 +01:00
cc17b3acaf Update deps
Mostly to free `symfony/phpunit-bridge`.

Also raise minimum version of node to 20, v16 is unmaintained since October 2023.
2023-12-22 14:41:05 +01:00
33 changed files with 1674 additions and 1513 deletions

View File

@ -17,12 +17,12 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
uses: "actions/checkout@v4"
- name: "Install Node"
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: ".nvmrc"
- name: "Install dependencies with Yarn"
run: "yarn install"

View File

@ -17,7 +17,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
uses: "actions/checkout@v4"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"

View File

@ -40,7 +40,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
uses: "actions/checkout@v4"
with:
fetch-depth: 2
@ -106,7 +106,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
uses: "actions/checkout@v4"
with:
fetch-depth: 2

View File

@ -22,7 +22,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
uses: "actions/checkout@v4"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"

View File

@ -16,7 +16,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
uses: "actions/checkout@v4"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"

2
.nvmrc
View File

@ -1 +1 @@
16
20

View File

@ -1,5 +1,15 @@
# Changelog
## [2.6.8](https://github.com/wallabag/wallabag/tree/2.6.8)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.7...2.6.8)
### Fixes
* Update deps & Node 20 by @j0k3r in https://github.com/wallabag/wallabag/pull/7134
* Fix dark mode disabled url 2.6 by @Simounet in https://github.com/wallabag/wallabag/pull/7133
* Make database dependent commands lazy by @yguedidi in https://github.com/wallabag/wallabag/pull/7142
* Fix docker setup by @yguedidi in https://github.com/wallabag/wallabag/pull/7141
* Remove session-based redirection by @yguedidi in https://github.com/wallabag/wallabag/pull/7140
## [2.6.7](https://github.com/wallabag/wallabag/tree/2.6.7)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.6...2.6.7)

View File

@ -85,6 +85,7 @@
background-color: #2f2f2f;
}
.mass-action-tags .mass-action-tags-input.mass-action-tags-input,
.side-nav li:not(.logo) > a:hover,
.side-nav .collapsible-header:hover,
.side-nav.fixed .collapsible-header:hover {
@ -131,6 +132,10 @@
color: #abb2bf;
}
input[type="url"]:not(.browser-default):disabled {
color: #9e9e9e;
}
.input-field.nav-panel-add.disabled,
.input-field.nav-panel-add.disabled input {
background-color: transparent;

View File

@ -268,9 +268,23 @@ services:
arguments:
$baseFolder: "%kernel.project_dir%/web/assets/images"
Wallabag\CoreBundle\Command\CleanDownloadedImagesCommand:
tags:
- { name: console.command, command: 'wallabag:clean-downloaded-images' }
Wallabag\CoreBundle\Command\CleanDuplicatesCommand:
tags:
- { name: console.command, command: 'wallabag:clean-duplicates' }
Wallabag\CoreBundle\Command\ExportCommand:
arguments:
$projectDir: '%kernel.project_dir%'
tags:
- { name: console.command, command: 'wallabag:export' }
Wallabag\CoreBundle\Command\GenerateUrlHashesCommand:
tags:
- { name: console.command, command: 'wallabag:generate-hashed-urls' }
Wallabag\CoreBundle\Command\InstallCommand:
arguments:
@ -279,6 +293,26 @@ services:
$defaultSettings: '%wallabag_core.default_internal_settings%'
$defaultIgnoreOriginInstanceRules: '%wallabag_core.default_ignore_origin_instance_rules%'
Wallabag\CoreBundle\Command\ListUserCommand:
tags:
- { name: console.command, command: 'wallabag:user:list' }
Wallabag\CoreBundle\Command\ReloadEntryCommand:
tags:
- { name: console.command, command: 'wallabag:entry:reload' }
Wallabag\CoreBundle\Command\ShowUserCommand:
tags:
- { name: console.command, command: 'wallabag:user:show' }
Wallabag\CoreBundle\Command\TagAllCommand:
tags:
- { name: console.command, command: 'wallabag:tag:all' }
Wallabag\ImportBundle\Command\ImportCommand:
tags:
- { name: console.command, command: 'wallabag:import' }
wallabag_core.entry.download_images.client:
alias: 'httplug.client.wallabag_core.entry.download_images'

View File

@ -1,5 +1,5 @@
wallabag_core:
version: 2.6.7
version: 2.6.8
paypal_url: "https://liberapay.com/wallabag/donate"
languages:
en: 'English'

View File

@ -170,7 +170,7 @@
"symfony/css-selector": "^4.4",
"symfony/debug-bundle": "^4.4",
"symfony/maker-bundle": "^1.18",
"symfony/phpunit-bridge": "~6.0",
"symfony/phpunit-bridge": "^6.0",
"symfony/var-dumper": "^4.4",
"symfony/web-profiler-bundle": "^4.4",
"symfony/web-server-bundle": "^4.4"

864
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
FROM php:8.1-fpm AS rootless
ARG DEBIAN_FRONTEND=noninteractive
ARG NODE_VERSION=16
ARG NODE_VERSION=20
RUN apt-get update \
&& apt-get install -y \
@ -33,8 +33,7 @@ RUN apt-get update && apt-get install -y \
zlib1g-dev \
git \
build-essential \
nodejs \
npm
nodejs
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp
RUN docker-php-ext-install -j "$(nproc)" \
bcmath \

View File

@ -7,7 +7,7 @@
"doc": "docs"
},
"engines": {
"node": ">=16"
"node": ">=20"
},
"repository": {
"type": "git",

View File

@ -45,11 +45,6 @@ parameters:
count: 1
path: tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php
-
message: "#^Call to method generate\\(\\) on an unknown class PHPUnit_Framework_MockObject_MockObject\\.$#"
count: 2
path: tests/Wallabag/CoreBundle/Helper/RedirectTest.php
-
message: "#^Property Tests\\\\Wallabag\\\\CoreBundle\\\\Helper\\\\RedirectTest\\:\\:\\$routerMock has unknown class PHPUnit_Framework_MockObject_MockObject as its type\\.$#"
count: 1

View File

@ -32,6 +32,7 @@ use Wallabag\CoreBundle\Form\Type\IgnoreOriginUserRuleType;
use Wallabag\CoreBundle\Form\Type\TaggingRuleImportType;
use Wallabag\CoreBundle\Form\Type\TaggingRuleType;
use Wallabag\CoreBundle\Form\Type\UserInformationType;
use Wallabag\CoreBundle\Helper\Redirect;
use Wallabag\CoreBundle\Repository\ConfigRepository;
use Wallabag\CoreBundle\Repository\EntryRepository;
use Wallabag\CoreBundle\Repository\IgnoreOriginUserRuleRepository;
@ -48,8 +49,9 @@ class ConfigController extends AbstractController
private TagRepository $tagRepository;
private AnnotationRepository $annotationRepository;
private ConfigRepository $configRepository;
private Redirect $redirectHelper;
public function __construct(EntityManagerInterface $entityManager, UserManagerInterface $userManager, EntryRepository $entryRepository, TagRepository $tagRepository, AnnotationRepository $annotationRepository, ConfigRepository $configRepository)
public function __construct(EntityManagerInterface $entityManager, UserManagerInterface $userManager, EntryRepository $entryRepository, TagRepository $tagRepository, AnnotationRepository $annotationRepository, ConfigRepository $configRepository, Redirect $redirectHelper)
{
$this->entityManager = $entityManager;
$this->userManager = $userManager;
@ -57,6 +59,7 @@ class ConfigController extends AbstractController
$this->tagRepository = $tagRepository;
$this->annotationRepository = $annotationRepository;
$this->configRepository = $configRepository;
$this->redirectHelper = $redirectHelper;
}
/**
@ -646,7 +649,9 @@ class ConfigController extends AbstractController
$this->entityManager->persist($user);
$this->entityManager->flush();
return $this->redirect($request->getSession()->get('prevUrl'));
$redirectUrl = $this->redirectHelper->to($request->query->get('redirect'));
return $this->redirect($redirectUrl);
}
/**

View File

@ -15,7 +15,6 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\Tag;
@ -128,7 +127,7 @@ class EntryController extends AbstractController
$this->entityManager->flush();
}
$redirectUrl = $this->redirectHelper->to($request->getSession()->get('prevUrl'));
$redirectUrl = $this->redirectHelper->to($request->query->get('redirect'));
return $this->redirect($redirectUrl);
}
@ -390,7 +389,6 @@ class EntryController extends AbstractController
public function viewAction(Entry $entry)
{
$this->checkUserAction($entry);
$this->get('session')->set('prevUrl', $this->generateUrl('view', ['id' => $entry->getId()]));
return $this->render(
'@WallabagCore/Entry/entry.html.twig',
@ -452,7 +450,7 @@ class EntryController extends AbstractController
$message
);
$redirectUrl = $this->redirectHelper->to($request->getSession()->get('prevUrl'));
$redirectUrl = $this->redirectHelper->to($request->query->get('redirect'));
return $this->redirect($redirectUrl);
}
@ -482,7 +480,7 @@ class EntryController extends AbstractController
$message
);
$redirectUrl = $this->redirectHelper->to($request->getSession()->get('prevUrl'));
$redirectUrl = $this->redirectHelper->to($request->query->get('redirect'));
return $this->redirect($redirectUrl);
}
@ -502,8 +500,7 @@ class EntryController extends AbstractController
// to avoid redirecting to the deleted entry. Ugh.
$url = $this->generateUrl(
'view',
['id' => $entry->getId()],
UrlGeneratorInterface::ABSOLUTE_PATH
['id' => $entry->getId()]
);
// entry deleted, dispatch event about it!
@ -518,7 +515,7 @@ class EntryController extends AbstractController
);
// don't redirect user to the deleted entry (check that the referer doesn't end with the same url)
$prev = $request->getSession()->get('prevUrl');
$prev = $request->query->get('redirect', '');
$to = (1 !== preg_match('#' . $url . '$#i', $prev) ? $prev : null);
$redirectUrl = $this->redirectHelper->to($to);
@ -617,7 +614,6 @@ class EntryController extends AbstractController
{
$searchTerm = (isset($request->get('search_entry')['term']) ? $request->get('search_entry')['term'] : '');
$currentRoute = (null !== $request->query->get('currentRoute') ? $request->query->get('currentRoute') : '');
$request->getSession()->set('prevUrl', $request->getRequestUri());
$formOptions = [];

View File

@ -104,7 +104,7 @@ class TagController extends AbstractController
$this->entityManager->flush();
}
$redirectUrl = $this->redirectHelper->to($request->getSession()->get('prevUrl'), '', true);
$redirectUrl = $this->redirectHelper->to($request->query->get('redirect'), true);
return $this->redirect($redirectUrl);
}
@ -185,7 +185,7 @@ class TagController extends AbstractController
$form = $this->createForm(RenameTagType::class, new Tag());
$form->handleRequest($request);
$redirectUrl = $this->redirectHelper->to($request->getSession()->get('prevUrl'), '', true);
$redirectUrl = $this->redirectHelper->to($request->query->get('redirect'), true);
if ($form->isSubmitted() && $form->isValid()) {
$newTag = new Tag();
@ -257,7 +257,7 @@ class TagController extends AbstractController
$this->entityManager->flush();
}
return $this->redirect($this->redirectHelper->to($request->getSession()->get('prevUrl'), '', true));
return $this->redirect($this->redirectHelper->to($request->query->get('redirect'), true));
}
/**
@ -279,7 +279,7 @@ class TagController extends AbstractController
$this->entityManager->remove($tag);
$this->entityManager->flush();
}
$redirectUrl = $this->redirectHelper->to($request->getSession()->get('prevUrl'), '', true);
$redirectUrl = $this->redirectHelper->to($request->query->get('redirect'), true);
return $this->redirect($redirectUrl);
}

View File

@ -2,6 +2,7 @@
namespace Wallabag\CoreBundle\Helper;
use GuzzleHttp\Psr7\Uri;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Wallabag\CoreBundle\Entity\Config;
@ -23,16 +24,23 @@ class Redirect
/**
* @param string $url URL to redirect
* @param string $fallback Fallback URL if $url is null
* @param bool $ignoreActionMarkAsRead Ignore configured action when mark as read
*
* @return string
*/
public function to($url, $fallback = '', $ignoreActionMarkAsRead = false)
public function to($url, $ignoreActionMarkAsRead = false)
{
$user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
if (!$user instanceof User) {
if (null === $url) {
return $this->router->generate('homepage');
}
if (!Uri::isAbsolutePathReference(new Uri($url))) {
return $this->router->generate('homepage');
}
return $url;
}
@ -41,14 +49,14 @@ class Redirect
return $this->router->generate('homepage');
}
if (null !== $url) {
return $url;
}
if ('' === $fallback) {
if (null === $url) {
return $this->router->generate('homepage');
}
return $fallback;
if (!Uri::isAbsolutePathReference(new Uri($url))) {
return $this->router->generate('homepage');
}
return $url;
}
}

View File

@ -7,18 +7,20 @@
</div>
</div>
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
<ul class="tools right">
<li>
<a title="{{ 'entry.list.show_same_domain'|trans }}" class="tool grey-text" href="{{ path('same_domain', {'id': entry.id}) }}" data-action="same_domain" data-entry-id="{{ entry.id }}"><i class="material-icons">language</i></a>
<a title="{{ 'entry.list.show_same_domain'|trans }}" class="tool grey-text" href="{{ path('same_domain', {'id': entry.id, redirect: current_path}) }}" data-action="same_domain" data-entry-id="{{ entry.id }}"><i class="material-icons">language</i></a>
</li>
<li>
<a title="{{ 'entry.list.toogle_as_read'|trans }}" class="tool grey-text" href="{{ path('archive_entry', {'id': entry.id}) }}" data-action="archived" data-entry-id="{{ entry.id }}"><i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i></a>
<a title="{{ 'entry.list.toogle_as_read'|trans }}" class="tool grey-text" href="{{ path('archive_entry', {'id': entry.id, redirect: current_path}) }}" data-action="archived" data-entry-id="{{ entry.id }}"><i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i></a>
</li>
<li>
<a title="{{ 'entry.list.toogle_as_star'|trans }}" class="tool grey-text" href="{{ path('star_entry', {'id': entry.id}) }}" data-action="star" data-entry-id="{{ entry.id }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i></a>
<a title="{{ 'entry.list.toogle_as_star'|trans }}" class="tool grey-text" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" data-action="star" data-entry-id="{{ entry.id }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i></a>
</li>
<li>
<a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" data-action-confirm="{{ 'entry.confirm.delete'|trans }}" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id}) }}" data-action="delete" data-entry-id="{{ entry.id }}"><i class="material-icons">delete</i></a>
<a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" data-action-confirm="{{ 'entry.confirm.delete'|trans }}" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}" data-action="delete" data-entry-id="{{ entry.id }}"><i class="material-icons">delete</i></a>
</li>
</ul>
</div>

View File

@ -9,12 +9,15 @@
</div>
{% endif %}
{% include "@WallabagCore/Entry/Card/_content.html.twig" with {'entry': entry, 'withMetadata': true, 'subClass': 'metadata'} only %}
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
<ul class="tools-list hide-on-small-only">
<li>
<a title="{{ 'entry.list.show_same_domain'|trans }}" class="tool grey-text" href="{{ path('same_domain', {'id': entry.id}) }}"><i class="material-icons">language</i></a>
<a title="{{ 'entry.list.toogle_as_read'|trans }}" class="tool grey-text" href="{{ path('archive_entry', {'id': entry.id}) }}"><i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i></a>
<a title="{{ 'entry.list.toogle_as_star'|trans }}" class="tool grey-text" href="{{ path('star_entry', {'id': entry.id}) }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i></a>
<a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id}) }}"><i class="material-icons">delete</i></a>
<a title="{{ 'entry.list.show_same_domain'|trans }}" class="tool grey-text" href="{{ path('same_domain', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">language</i></a>
<a title="{{ 'entry.list.toogle_as_read'|trans }}" class="tool grey-text" href="{{ path('archive_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i></a>
<a title="{{ 'entry.list.toogle_as_star'|trans }}" class="tool grey-text" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i></a>
<a title="{{ 'entry.list.delete'|trans }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" class="tool grey-text delete" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">delete</i></a>
</li>
</ul>
</div>

View File

@ -4,7 +4,8 @@
<li class="chip">
<a class="chip-label" href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a>
{% if withRemove is defined and withRemove == true %}
<a class="chip-action" href="{{ path('remove_tag', {'entry': entryId, 'tag': tag.id}) }}" onclick="return confirm('{{ 'entry.confirm.delete_tag'|trans|escape('js') }}')">
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
<a class="chip-action" href="{{ path('remove_tag', {'entry': entryId, 'tag': tag.id, redirect: current_path}) }}" onclick="return confirm('{{ 'entry.confirm.delete_tag'|trans|escape('js') }}')">
<i class="material-icons vertical-align-middle">delete</i>
</a>
{% endif %}

View File

@ -19,18 +19,19 @@
{% endblock %}
{% block content %}
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
{% set list_mode = app.user.config.listMode %}
{% set entries_with_archived_class_routes = ['tag_entries', 'search', 'all'] %}
{% set current_route = app.request.attributes.get('_route') %}
{% if current_route == 'homepage' %}
{% set current_route = 'unread' %}
{% endif %}
<form name="form_mass_action" action="{{ path('mass_action') }}" method="post">
<form name="form_mass_action" action="{{ path('mass_action', {redirect: current_path}) }}" method="post">
<div class="results">
<div class="nb-results">
{{ 'entry.list.number_on_the_page'|trans({'%count%': entries.count}) }}
{% if entries.count > 0 %}
<a class="results-item" href="{{ path('switch_view_mode') }}"><i class="material-icons">{% if list_mode == 0 %}view_list{% else %}view_module{% endif %}</i></a>
<a class="results-item" href="{{ path('switch_view_mode', {redirect: current_path}) }}"><i class="material-icons">{% if list_mode == 0 %}view_list{% else %}view_module{% endif %}</i></a>
{% endif %}
{% if entries.count > 0 %}
<label for="mass-action-inputs-displayed" class="mass-action-toggle results-item tooltipped" data-position="right" data-delay="50" data-tooltip="{{ 'entry.list.toggle_mass_action'|trans }}"><i class="material-icons">library_add_check</i></label>
@ -39,7 +40,7 @@
{% include "@WallabagCore/Entry/_feed_link.html.twig" %}
{% endif %}
</div>
{% if current_route == 'search' %}<div><a href="{{ path('tag_this_search', {'filter': searchTerm, 'currentRoute': app.request.get('currentRoute')}) }}" title="{{ 'entry.list.assign_search_tag'|trans }}">{{ 'entry.list.assign_search_tag'|trans }}</a></div>{% endif %}
{% if current_route == 'search' %}<div><a href="{{ path('tag_this_search', {'filter': searchTerm, 'currentRoute': app.request.get('currentRoute'), redirect: current_path}) }}" title="{{ 'entry.list.assign_search_tag'|trans }}">{{ 'entry.list.assign_search_tag'|trans }}</a></div>{% endif %}
{% if entries.getNbPages > 1 %}
{{ pagerfanta(entries, 'default_wallabag') }}
{% endif %}

View File

@ -4,6 +4,8 @@
{% block body_class %}entry{% endblock %}
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
{% block menu %}
<div class="progress">
<div class="determinate"></div>
@ -24,12 +26,12 @@
</ul>
<ul class="right">
<li>
<a class="waves-effect" title="{{ 'entry.view.left_menu.set_as_read'|trans }}" href="{{ path('archive_entry', {'id': entry.id}) }}" id="markAsRead">
<a class="waves-effect" title="{{ 'entry.view.left_menu.set_as_read'|trans }}" href="{{ path('archive_entry', {'id': entry.id, redirect: current_path}) }}" id="markAsRead">
<i class="material-icons small">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i>
</a>
</li>
<li>
<a class="waves-effect" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', {'id': entry.id}) }}" id="setFav">
<a class="waves-effect" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" id="setFav">
<i class="material-icons small">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i>
</a>
</li>
@ -67,7 +69,7 @@
{% endif %}
<li class="bold hide-on-med-and-down">
<a class="waves-effect collapsible-header markasread" title="{{ mark_as_read_label|trans }}" href="{{ path('archive_entry', {'id': entry.id}) }}" id="markAsRead">
<a class="waves-effect collapsible-header markasread" title="{{ mark_as_read_label|trans }}" href="{{ path('archive_entry', {'id': entry.id, redirect: current_path}) }}" id="markAsRead">
<i class="material-icons small">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i>
<span>{{ mark_as_read_label|trans }}</span>
</a>
@ -75,14 +77,14 @@
</li>
<li class="bold hide-on-med-and-down">
<a class="waves-effect collapsible-header favorite" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', {'id': entry.id}) }}" id="setFav">
<a class="waves-effect collapsible-header favorite" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}" id="setFav">
<i class="material-icons spall">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i>
<span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span>
</a>
<div class="collapsible-body"></div>
</li>
<li class="bold border-bottom">
<a class="waves-effect collapsible-header delete" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" title="{{ 'entry.view.left_menu.delete'|trans }}" href="{{ path('delete_entry', {'id': entry.id}) }}">
<a class="waves-effect collapsible-header delete" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')" title="{{ 'entry.view.left_menu.delete'|trans }}" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}">
<i class="material-icons small">delete</i>
<span>{{ 'entry.view.left_menu.delete'|trans }}</span>
</a>
@ -298,9 +300,9 @@
<i class="material-icons">menu</i>
</a>
<ul>
<li><a class="btn-floating" href="{{ path('archive_entry', {'id': entry.id}) }}"><i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i></a></li>
<li><a class="btn-floating" href="{{ path('star_entry', {'id': entry.id}) }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i></a></li>
<li><a class="btn-floating" href="{{ path('delete_entry', {'id': entry.id}) }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')"><i class="material-icons">delete</i></a></li>
<li><a class="btn-floating" href="{{ path('archive_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}unarchive{% endif %}</i></a></li>
<li><a class="btn-floating" href="{{ path('star_entry', {'id': entry.id, redirect: current_path}) }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i></a></li>
<li><a class="btn-floating" href="{{ path('delete_entry', {'id': entry.id, redirect: current_path}) }}" onclick="return confirm('{{ 'entry.confirm.delete'|trans|escape('js') }}')"><i class="material-icons">delete</i></a></li>
</ul>
</div>
</div>

View File

@ -3,6 +3,8 @@
{% block title %}{{ 'tag.page_title'|trans }}{% endblock %}
{% block content %}
{% set current_path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
<div class="results clearfix">
{{ 'tag.list.number_on_the_page'|trans({'%count%': tags|length}) }}
</div>
@ -18,7 +20,7 @@
{{ tag.label }}&nbsp;({{ tag.nbEntries }})
</a>
{% if renameForms is defined and renameForms[tag.id] is defined %}
<form class="card-tag-form hidden" data-handle="tag-rename-form" action="{{ path('tag_rename', {'slug': tag.slug}) }}" method="POST">
<form class="card-tag-form hidden" data-handle="tag-rename-form" action="{{ path('tag_rename', {'slug': tag.slug, redirect: current_path}) }}" method="POST">
{{ form_widget(renameForms[tag.id].label, {'attr': {'value': tag.label}}) }}
{{ form_rest(renameForms[tag.id]) }}
</form>
@ -26,7 +28,7 @@
<i class="material-icons">mode_edit</i>
</a>
{% endif %}
<a id="delete-{{ tag.slug }}" href="{{ path('tag_delete', {'slug': tag.slug}) }}" class="card-tag-icon card-tag-delete" onclick="return confirm('{{ 'tag.confirm.delete'|trans({'%name%': tag.label})|escape('js') }}')">
<a id="delete-{{ tag.slug }}" href="{{ path('tag_delete', {'slug': tag.slug, redirect: current_path}) }}" class="card-tag-icon card-tag-delete" onclick="return confirm('{{ 'tag.confirm.delete'|trans({'%name%': tag.label})|escape('js') }}')">
<i class="material-icons">delete</i>
</a>
{% if app.user.config.feedToken %}

View File

@ -1302,8 +1302,10 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->flush();
$client->request('GET', '/view/' . $entry->getId());
$client->request('GET', '/archive/' . $entry->getId());
$crawler = $client->request('GET', '/view/' . $entry->getId());
$link = $crawler->filter('a[id="markAsRead"]')->link();
$client->click($link);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('/view/' . $entry->getId(), $client->getResponse()->headers->get('location'));
@ -1656,7 +1658,7 @@ class EntryControllerTest extends WallabagCoreTestCase
// the deletion link of the first tag
$link = $crawler->filter('body div#article div.tools ul.tags li.chip a')->extract(['href'])[1];
$this->assertSame(sprintf('/remove-tag/%s/%s', $entry->getId(), $tag->getId()), $link);
$this->assertStringStartsWith(sprintf('/remove-tag/%s/%s', $entry->getId(), $tag->getId()), $link);
}
public function testRandom()

View File

@ -123,9 +123,11 @@ class TagControllerTest extends WallabagCoreTestCase
$this->getEntityManager()->clear();
// We make a first request to set an history and test redirection after tag deletion
$client->request('GET', '/view/' . $entry->getId());
$crawler = $client->request('GET', '/view/' . $entry->getId());
$entryUri = $client->getRequest()->getRequestUri();
$client->request('GET', '/remove-tag/' . $entry->getId() . '/' . $tag->getId());
$link = $crawler->filter('a[href^="/remove-tag/' . $entry->getId() . '/' . $tag->getId() . '"]')->link();
$client->click($link);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertSame($entryUri, $client->getResponse()->getTargetUrl());

View File

@ -33,7 +33,7 @@ class RedirectTest extends TestCase
$this->routerMock->expects($this->any())
->method('generate')
->with('homepage')
->willReturn('homepage');
->willReturn('/');
$this->user = new User();
$this->user->setName('youpi');
@ -59,18 +59,11 @@ class RedirectTest extends TestCase
$this->redirect = new Redirect($this->routerMock, $tokenStorage);
}
public function testRedirectToNullWithFallback()
{
$redirectUrl = $this->redirect->to(null, 'fallback');
$this->assertSame('fallback', $redirectUrl);
}
public function testRedirectToNullWithoutFallback()
public function testRedirectToNull()
{
$redirectUrl = $this->redirect->to(null);
$this->assertSame($this->routerMock->generate('homepage'), $redirectUrl);
$this->assertSame('/', $redirectUrl);
}
public function testRedirectToValidUrl()
@ -80,6 +73,13 @@ class RedirectTest extends TestCase
$this->assertSame('/unread/list', $redirectUrl);
}
public function testRedirectToAbsoluteUrl()
{
$redirectUrl = $this->redirect->to('https://www.google.com/');
$this->assertSame('/', $redirectUrl);
}
public function testWithNotLoggedUser()
{
$redirect = new Redirect($this->routerMock, new TokenStorage());
@ -94,24 +94,24 @@ class RedirectTest extends TestCase
$redirectUrl = $this->redirect->to('/unread/list');
$this->assertSame($this->routerMock->generate('homepage'), $redirectUrl);
$this->assertSame('/', $redirectUrl);
}
public function testUserForRedirectWithIgnoreActionMarkAsRead()
{
$this->user->getConfig()->setActionMarkAsRead(Config::REDIRECT_TO_HOMEPAGE);
$redirectUrl = $this->redirect->to('/unread/list', '', true);
$redirectUrl = $this->redirect->to('/unread/list', true);
$this->assertSame('/unread/list', $redirectUrl);
}
public function testUserForRedirectNullWithFallbackWithIgnoreActionMarkAsRead()
public function testUserForRedirectNullWithIgnoreActionMarkAsRead()
{
$this->user->getConfig()->setActionMarkAsRead(Config::REDIRECT_TO_HOMEPAGE);
$redirectUrl = $this->redirect->to(null, 'fallback', true);
$redirectUrl = $this->redirect->to(null, true);
$this->assertSame('fallback', $redirectUrl);
$this->assertSame('/', $redirectUrl);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2076
yarn.lock

File diff suppressed because it is too large Load Diff