mirror of
https://github.com/wallabag/wallabag.git
synced 2025-01-10 17:05:26 +00:00
Merge pull request #1446 from wallabag/v2-language-config
[WIP] language selection on config screen
This commit is contained in:
commit
fcc6949d4a
13 changed files with 283 additions and 12 deletions
|
@ -25,6 +25,11 @@ framework:
|
|||
fragments: ~
|
||||
http_method_override: true
|
||||
|
||||
wallabag_core:
|
||||
languages:
|
||||
en: 'English'
|
||||
fr: 'Français'
|
||||
|
||||
# Twig Configuration
|
||||
twig:
|
||||
debug: "%kernel.debug%"
|
||||
|
|
|
@ -18,3 +18,15 @@ services:
|
|||
public: false
|
||||
tags:
|
||||
- { name: twig.extension }
|
||||
|
||||
wallabag.locale_listener:
|
||||
class: Wallabag\CoreBundle\EventListener\LocaleListener
|
||||
arguments: ["%kernel.default_locale%"]
|
||||
tags:
|
||||
- { name: kernel.event_subscriber }
|
||||
|
||||
wallabag.user_locale_listener:
|
||||
class: Wallabag\CoreBundle\EventListener\UserLocaleListener
|
||||
arguments: ["@session"]
|
||||
tags:
|
||||
- { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }
|
||||
|
|
|
@ -42,7 +42,7 @@ class ConfigController extends Controller
|
|||
|
||||
$this->get('session')->getFlashBag()->add(
|
||||
'notice',
|
||||
'Config saved'
|
||||
'Config saved. Some parameters will be considered after disconnection.'
|
||||
);
|
||||
|
||||
return $this->redirect($this->generateUrl('config'));
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
|
||||
class Configuration implements ConfigurationInterface
|
||||
{
|
||||
public function getConfigTreeBuilder()
|
||||
{
|
||||
$treeBuilder = new TreeBuilder();
|
||||
$rootNode = $treeBuilder->root('wallabag_core');
|
||||
|
||||
$rootNode
|
||||
->children()
|
||||
->arrayNode('languages')
|
||||
->prototype('scalar')->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
|
||||
return $treeBuilder;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,10 @@ class WallabagCoreExtension extends Extension
|
|||
{
|
||||
public function load(array $configs, ContainerBuilder $container)
|
||||
{
|
||||
$configuration = new Configuration();
|
||||
$config = $this->processConfiguration($configuration, $configs);
|
||||
$container->setParameter('wallabag_core.languages', $config['languages']);
|
||||
|
||||
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
|
||||
$loader->load('services.yml');
|
||||
}
|
||||
|
|
44
src/Wallabag/CoreBundle/EventListener/LocaleListener.php
Normal file
44
src/Wallabag/CoreBundle/EventListener/LocaleListener.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* @see http://symfony.com/doc/current/cookbook/session/locale_sticky_session.html
|
||||
*/
|
||||
class LocaleListener implements EventSubscriberInterface
|
||||
{
|
||||
private $defaultLocale;
|
||||
|
||||
public function __construct($defaultLocale = 'en')
|
||||
{
|
||||
$this->defaultLocale = $defaultLocale;
|
||||
}
|
||||
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
if (!$request->hasPreviousSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// try to see if the locale has been set as a _locale routing parameter
|
||||
if ($locale = $request->attributes->get('_locale')) {
|
||||
$request->getSession()->set('_locale', $locale);
|
||||
} else {
|
||||
// if no explicit locale has been set on this request, use one from the session
|
||||
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
// must be registered before the default Locale listener
|
||||
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
|
||||
);
|
||||
}
|
||||
}
|
37
src/Wallabag/CoreBundle/EventListener/UserLocaleListener.php
Normal file
37
src/Wallabag/CoreBundle/EventListener/UserLocaleListener.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\EventListener;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||
|
||||
/**
|
||||
* Stores the locale of the user in the session after the
|
||||
* login. This can be used by the LocaleListener afterwards.
|
||||
*
|
||||
* @see http://symfony.com/doc/master/cookbook/session/locale_sticky_session.html
|
||||
*/
|
||||
class UserLocaleListener
|
||||
{
|
||||
/**
|
||||
* @var Session
|
||||
*/
|
||||
private $session;
|
||||
|
||||
public function __construct(Session $session)
|
||||
{
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InteractiveLoginEvent $event
|
||||
*/
|
||||
public function onInteractiveLogin(InteractiveLoginEvent $event)
|
||||
{
|
||||
$user = $event->getAuthenticationToken()->getUser();
|
||||
|
||||
if (null !== $user->getConfig()->getLanguage()) {
|
||||
$this->session->set('_locale', $user->getConfig()->getLanguage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,16 +9,20 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
|||
class ConfigType extends AbstractType
|
||||
{
|
||||
private $themes = array();
|
||||
private $languages = array();
|
||||
|
||||
/**
|
||||
* @param array $themes Themes come from the LiipThemeBundle (liip_theme.themes)
|
||||
* @param array $themes Themes come from the LiipThemeBundle (liip_theme.themes)
|
||||
* @param array $languages Languages come from configuration, array just code language as key and label as value
|
||||
*/
|
||||
public function __construct($themes)
|
||||
public function __construct($themes, $languages)
|
||||
{
|
||||
$this->themes = array_combine(
|
||||
$themes,
|
||||
array_map(function ($s) { return ucwords(strtolower(str_replace('-', ' ', $s))); }, $themes)
|
||||
);
|
||||
|
||||
$this->languages = $languages;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
|
@ -29,7 +33,9 @@ class ConfigType extends AbstractType
|
|||
'choices_as_values' => true,
|
||||
))
|
||||
->add('items_per_page')
|
||||
->add('language')
|
||||
->add('language', 'choice', array(
|
||||
'choices' => $this->languages,
|
||||
))
|
||||
->add('save', 'submit')
|
||||
;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ services:
|
|||
class: Wallabag\CoreBundle\Form\Type\ConfigType
|
||||
arguments:
|
||||
- %liip_theme.themes%
|
||||
- %wallabag_core.languages%
|
||||
tags:
|
||||
- { name: form.type, alias: config }
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ download the application: "téléchargez l'application"
|
|||
|
||||
# Flash messages
|
||||
Information updated: "Vos informations personnelles ont bien été mises à jour"
|
||||
Config saved: "Les paramètres de wallabag ont bien été mis à jour"
|
||||
"Config saved. Some parameters will be considered after disconnection.": "Les paramètres ont bien été mis à jour. Certains seront pris en compte après déconnexion."
|
||||
RSS information updated: "La configuration des flux RSS a bien été mise à jour"
|
||||
Password updated: "Votre mot de passe a bien été mis à jour"
|
||||
Entry starred: "Article ajouté dans les favoris"
|
||||
|
|
|
@ -46,7 +46,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
|
|||
$data = array(
|
||||
'config[theme]' => 0,
|
||||
'config[items_per_page]' => '30',
|
||||
'config[language]' => 'fr_FR',
|
||||
'config[language]' => 'en',
|
||||
);
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
@ -65,12 +65,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
|
|||
array(array(
|
||||
'config[theme]' => 0,
|
||||
'config[items_per_page]' => '',
|
||||
'config[language]' => 'fr_FR',
|
||||
)),
|
||||
array(array(
|
||||
'config[theme]' => 0,
|
||||
'config[items_per_page]' => '12',
|
||||
'config[language]' => '',
|
||||
'config[language]' => 'en',
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Tests\EventListener;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Wallabag\CoreBundle\EventListener\LocaleListener;
|
||||
|
||||
class LocaleListenerTest extends KernelTestCase
|
||||
{
|
||||
private function getEvent(Request $request)
|
||||
{
|
||||
return new GetResponseEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, HttpKernelInterface::MASTER_REQUEST);
|
||||
}
|
||||
|
||||
public function testWithoutSession()
|
||||
{
|
||||
$request = Request::create('/');
|
||||
|
||||
$listener = new LocaleListener('fr');
|
||||
$event = $this->getEvent($request);
|
||||
|
||||
$listener->onKernelRequest($event);
|
||||
$this->assertEquals('en', $request->getLocale());
|
||||
}
|
||||
|
||||
public function testWithPreviousSession()
|
||||
{
|
||||
$request = Request::create('/');
|
||||
// generate a previous session
|
||||
$request->cookies->set('MOCKSESSID', 'foo');
|
||||
$request->setSession(new Session(new MockArraySessionStorage()));
|
||||
|
||||
$listener = new LocaleListener('fr');
|
||||
$event = $this->getEvent($request);
|
||||
|
||||
$listener->onKernelRequest($event);
|
||||
$this->assertEquals('fr', $request->getLocale());
|
||||
}
|
||||
|
||||
public function testLocaleFromRequestAttribute()
|
||||
{
|
||||
$request = Request::create('/');
|
||||
// generate a previous session
|
||||
$request->cookies->set('MOCKSESSID', 'foo');
|
||||
$request->setSession(new Session(new MockArraySessionStorage()));
|
||||
$request->attributes->set('_locale', 'es');
|
||||
|
||||
$listener = new LocaleListener('fr');
|
||||
$event = $this->getEvent($request);
|
||||
|
||||
$listener->onKernelRequest($event);
|
||||
$this->assertEquals('en', $request->getLocale());
|
||||
$this->assertEquals('es', $request->getSession()->get('_locale'));
|
||||
}
|
||||
|
||||
public function testSubscribedEvents()
|
||||
{
|
||||
$request = Request::create('/');
|
||||
// generate a previous session
|
||||
$request->cookies->set('MOCKSESSID', 'foo');
|
||||
$request->setSession(new Session(new MockArraySessionStorage()));
|
||||
|
||||
$listener = new LocaleListener('fr');
|
||||
$event = $this->getEvent($request);
|
||||
|
||||
$dispatcher = new EventDispatcher();
|
||||
$dispatcher->addSubscriber($listener);
|
||||
|
||||
$dispatcher->dispatch(
|
||||
KernelEvents::REQUEST,
|
||||
$event
|
||||
);
|
||||
|
||||
$this->assertEquals('fr', $request->getLocale());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Tests\EventListener;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
use Wallabag\CoreBundle\EventListener\UserLocaleListener;
|
||||
use Wallabag\CoreBundle\Entity\Config;
|
||||
use Wallabag\UserBundle\Entity\User;
|
||||
|
||||
class UserLocaleListenerTest extends KernelTestCase
|
||||
{
|
||||
public function testWithLanguage()
|
||||
{
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
$listener = new UserLocaleListener($session);
|
||||
|
||||
$user = new User();
|
||||
$user->setEnabled(true);
|
||||
|
||||
$config = new Config($user);
|
||||
$config->setLanguage('fr');
|
||||
|
||||
$user->setConfig($config);
|
||||
|
||||
$userToken = new UsernamePasswordToken($user, '', 'test');
|
||||
$request = Request::create('/');
|
||||
$event = new InteractiveLoginEvent($request, $userToken);
|
||||
|
||||
$listener->onInteractiveLogin($event);
|
||||
|
||||
$this->assertEquals('fr', $session->get('_locale'));
|
||||
}
|
||||
|
||||
public function testWithoutLanguage()
|
||||
{
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
$listener = new UserLocaleListener($session);
|
||||
|
||||
$user = new User();
|
||||
$user->setEnabled(true);
|
||||
|
||||
$config = new Config($user);
|
||||
|
||||
$user->setConfig($config);
|
||||
|
||||
$userToken = new UsernamePasswordToken($user, '', 'test');
|
||||
$request = Request::create('/');
|
||||
$event = new InteractiveLoginEvent($request, $userToken);
|
||||
|
||||
$listener->onInteractiveLogin($event);
|
||||
|
||||
$this->assertEquals('', $session->get('_locale'));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue