I have problem in Symfony project with Symfony version 3.1.10. I got this project to finish translating and this is my first meeting with Symfony.
What is problem here: I have two language DE and EN, default language is DE. When someone go to login page or home page( where also is login form) and switch to EN and enter to login, its change locale to /de/ default language, after login. I spent few days on this bug and really I need help. I tried everything, but there is still no progress.
I followed Symfony documentation, how to configure translation, how to use Sticky user session and I created everything same, but bug is there agin. I will show my code below:
config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
parameters:
locale: de
framework:
#esi: ~
translator: { fallbacks: ["%locale%"] }
default_locale: "%locale%"
app/config/routing.yml
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
app:
resource: "@AppBundle/Controller/"
type: annotation
proreg:
path: /{_locale}/product/registration
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::productRegistrationAction }
prolist:
path: /{_locale}/profile/products
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::listAction }
prodel:
path: /{_locale}/profile/products/delete/{id}
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::deleteAction }
proadd:
path: /{_locale}/product/register
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::createAction }
app/config/security.yml
security:
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: fos_user_security_login
# csrf_token_generator: security.csrf.token_manager # Use form.csrf_provider instead for Symfony <2.4
always_use_default_target_path: false
logout: true
anonymous: true
# http_basic: ~
# http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: ~
# http://symfony.com/doc/current/cookbook/security/form_login_setup.html
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/sso/login_check, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/sso/settoken, role: ROLE_ADMIN }
- { path: ^/profile/products, role: ROLE_ADMIN }
- { path: ^/product/registration, role: ROLE_ADMIN }
app/Resources/FOSUserBundle/all.xml
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<import
resource="@FOSUserBundle/Resources/config/routing/security.xml"/>
<import
resource="@FOSUserBundle/Resources/config/routing/profile.xml"
prefix="/{_locale}/profile" />
<import
resource="@FOSUserBundle/Resources/config/routing/registration.xml"
prefix="/{_locale}/register" />
<import
resource="@FOSUserBundle/Resources/config/routing/resetting.xml"
prefix="/{_locale}/resetting" />
<import
resource="@FOSUserBundle/Resources/config/routing/change_password.xml"
prefix="/{_locale}/profile" />
</routes>
app/Resources/FOSUserBundle/security.xml
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_security_login" path="/{_locale}/login" methods="GET POST">
<default key="_controller">FOSUserBundle:Security:login</default>
</route>
<route id="fos_user_security_check" path="/login_check" methods="POST">
<default key="_controller">AppBundle:Security:check</default>
</route>
<route id="fos_user_security_logout" path="/logout" methods="GET POST">
<default key="_controller">FOSUserBundle:Security:logout</default>
</route>
</routes>
src/AppBundle/Controller/DefaultController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Security;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManager;
class DefaultController extends Controller
{
/**
* @Route("/{_locale}", name="homepage", defaults={"_locale": "de"})
*/
public function indexAction(Request $request)
{
// replace this example code with whatever you need
return $this->render('default/index.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
]);
}
src/AppBundle/Controller/SecurityController.php
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
// src/UserBundle/Controller/SecurityController.php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use FOS\UserBundle\Controller\SecurityController as BaseController;
class SecurityController extends BaseController
{
public function loginAction(Request $request)
{
$response = parent::loginAction(request);
// ... do custom stuff
$errors->messageData = "Test";
$errors->messageKey = "test";
$error = $error ? $error : $errors;
return $this->renderLogin(array(
'last_username' => $lastUsername,
'error' => $error,
//'csrf_token' => $csrfToken,
'origin' => $request->get("origin")));
}
public function checkAction()
{
$response = parent::checkAction();
die ("<pre>" .print_r($response). "</pre>");
}
}
src/AppBundle/Event/LocaleListener.php
// src/AppBundle/LocaleListener.php
namespace AppBundle\Event;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct($defaultLocale = 'de')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
//print_r($request->get('_locale'));
// 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 after the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 15)),
);
}
}
login form
<form action="{{ path("fos_user_security_check") }}" method="post" id="login-form" class="col-xs-12">
<div class="content">
<h2>{{ 'index.login.regcust'|trans }}</h2>
<p>{{ 'index.login.haveaccount'|trans }}</p>
<ul class="form-list">
<li class="form_element">
<label for="email" class="required">{{ 'index.login.email'|trans }}<em>*</em></label>
<div class="input-box">
<input type="hidden" name="origin" value="{{ origin }}" />
<input type="hidden" name="_target_path" value="{{ path("setSSOToken") }}" />
<input type="email" name="_username" value="" id="username" class="input-text required-entry validate-email" title="{{ 'index.login.email'|trans }}">
</div>
</li>
<li class="form_element">
<label for="pass" class="required">{{ 'index.login.password'|trans }}<em>*</em></label>
<div class="input-box input-box-password">
<input type="password" name="_password" class="input-text required-entry" id="password" title="{{ 'index.login.password'|trans }}">
<!--a href="" class="f-left forgot-password">{{ 'index.login.forgot'|trans }}</a-->
</div>
</li>
</ul>
<p class="required required_hint">
<em>*</em> {{ 'index.login.required'|trans }}
</p>
</div>
<div class="buttons-set">
<div class="button_wrapper">
<button type="submit" class="button" title="Anmelden" name="send" id="send2"><span><span>{{ 'index.login.submit'|trans }}</span></span></button>
</div>
</div>
</form>
If someone can help me how to fix this problem, i will be very grateful. Thanks