How to Customize Fos Userbundle Urls

How to customize FOS UserBundle URLs

How to override / change FOSUserBundle's routes

You can override i.e the /register route in your app/config/routing.yml by re-declaring it after importing FOSUserBundle's XML routes as resources.

fos_user_register:
resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
prefix: /register

# ...

fos_user_registration_register:
path: /account/register
defaults: { _controller: FOSUserBundle:Registration:register }

... or just change the prefix when importing:

fos_user_register:
resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
prefix: /account/register

# no need to override the route

The same goes for /login and /logout :

fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"

# ...

fos_user_security_login:
path: /account/login
defaults: { _controller: FOSUserBundle:Security:login, _method: POST }

fos_user_security_logout:
path: /account/login
defaults: { _controller: FOSUserBundle:Security:logout, _method: POST }

Another way to override login and logout url's

login and logout paths can aswell be configured directly in your app/config/security.yml:

security:
firewalls:
your_firewall:
# ...
form_login:
login_path: /account/login # instead of fos_user_security_login
# ...
logout:
path: /account/logout # instead of fos_user_security_logout
# ...

List of all of FOSUserBundle's routes in YAML format

You can directly change and then include these in your app/config/routing.yml ( no need to import the ones the bundle provides as resources then) ... or put them all into a single file and include that one as a resource...

# -> from @FOSUserBundle/Resources/routing/change_password.xml

fos_user_change_password:
pattern: /profile/password/change
defaults: { _controller: FOSUserBundle:ChangePassword:changePassword }
requirements:
_method: GET|POST

# -> from @FOSUserBundle/Resources/routing/group.xml

fos_user_group_list:
pattern: /groups/list
defaults: { _controller: FOSUserBundle:Group:list }
requirements:
_method: GET

fos_user_group_new:
pattern: /groups/new
pattern:
defaults: { _controller: FOSUserBundle:Group:new }
requirements:
_method: GET

fos_user_group_show:
pattern: /groups/{groupname}
defaults: { _controller: FOSUserBundle:Group:show }
requirements:
_method: GET

fos_user_group_edit:
pattern: /groups/{groupname}/edit
defaults: { _controller: FOSUserBundle:Group:edit }
requirements:
_method: GET|POST

fos_user_group_delete:
pattern: /groups/{groupname}/delete
defaults: { _controller: FOSUserBundle:Group:delete }
requirements:
_method: GET

# -> from @FOSUserBundle/Resources/routing/profile.xml

fos_user_profile_show:
pattern: /profile/show
defaults: { _controller: FOSUserBundle:Profile:show }
requirements:
_method: GET

fos_user_profile_edit:
pattern: /profile/edit
defaults: { _controller: FOSUserBundle:Profile:edit }
requirements:
_method: GET|POST

# -> from @FOSUserBundle/Resources/routing/registration.xml

fos_user_registration_register:
pattern: /registration
defaults: { _controller: FOSUserBundle:Registration:register }
requirements:
_method: GET|POST

fos_user_registration_check_email:
pattern: /registration/check-email
defaults: { _controller: FOSUserBundle:Registration:checkEmail }
requirements:
_method: GET

fos_user_registration_confirm:
pattern: /registration/confirm/{token}
defaults: { _controller: FOSUserBundle:Registration:confirm }
requirements:
_method: GET

fos_user_registration_confirmed:
pattern: /registration/confirmed
defaults: { _controller: FOSUserBundle:Registration:confirmed }
requirements:
_method: GET

# -> from @FOSUserBundle/Resources/routing/resetting.xml

fos_user_resetting_request:
pattern: /profile/password/reset
defaults: { _controller: FOSUserBundle:Resetting:request }
requirements:
_method: GET

fos_user_resetting_send_email:
pattern: /profile/password/reset
defaults: { _controller: FOSUserBundle:Resetting:sendEmail }
requirements:
_method: POST

fos_user_resetting_check_email:
pattern: /profile/password/reset/check-email
defaults: { _controller: FOSUserBundle:Registration:checkEmail }
requirements:
_method: GET

fos_user_resetting_reset:
pattern: /profile/password/reset/{token}
defaults: { _controller: FOSUserBundle:Registration:reset }
requirements:
_method: GET|POST

# -> from @FOSUserBundle/Resources/routing/security.xml

fos_user_security_login:
pattern: /login
defaults: { _controller: FOSUserBundle:Security:login }
requirements:
_method: GET|POST

fos_user_security_check:
pattern: /login_check
defaults: { _controller: FOSUserBundle:Security:check }

fos_user_security_logout:
pattern: /logout
defaults: { _controller: FOSUserBundle:Security:logout }
requirements:
_method: GET|POST

Dynamically Styling an FOS UserBundle Login Page

You can override the renderLogin method of the SecurityController. Here is how you could do it:

namespace Acme\UserBundle\Controller;

use FOS\UserBundle\Controller\SecurityController as BaseController;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\Security\Core\SecurityContext;

use Symfony\Component\HttpFoundation\Request;

class SecurityController extends BaseController
{
/**
* Overriding the FOS default method so that we can choose a template
*/
protected function renderLogin(array $data)
{
$template = $this->getTemplate();

return $this->container->get('templating')->renderResponse($template, $data);
}

/**
* You get the subdomain and return the correct template
*/
public function getTemplate(){

$subdomain = $this->container->get('request')->getHost();

if ($subdomain === "microsite1.mainsite.com"){
$template = sprintf('AcmeUserBundle:Security:loginMicrosite1.html.%s', $this->container->getParameter('fos_user.template.engine'));
}
elseif($subdomain === "microsite2.mainsite.com"){
$template = sprintf('AcmeUserBundle:Security:loginMicrosite2.html.%s', $this->container->getParameter('fos_user.template.engine'));
}
//blablabla
//Customize with what you need here.

return $template;
}

FosUserBundle: How to override the default /profile path to custom path?

If you look at @FOSUserBundle/Resources/config/routing/profile.xml, you will see the following routings. You can overwrite any routing (or other configuration) by using the same name in your own routing

<route id="fos_user_profile_show" path="/" methods="GET">
<default key="_controller">FOSUserBundle:Profile:show</default>
</route>

<route id="fos_user_profile_edit" path="/edit" methods="GET POST">
<default key="_controller">FOSUserBundle:Profile:edit</default>
</route>

In your own routing.yml you'd simply overwrite like this:

fos_user_profile_show:
path: /profile/{id}
defaults: { _controller: AppBundle:Profile:show }

fos_user_profile_edit:
path: /profile/edit/{id}
defaults: { _controller: AppBundle:Profile:edit }

Note that most likely you are no longer using the default ProfileController, but instead have your own ProfileController extending the FOSUserBundle ProfileController. That's why I also changed the controller to AppBundle:Profile:edit, but obviously this needs to match your code.

Also note the {id} needs to be implemented in your code, ex.:

public function showAction(Request $request, $id)

Also see here for a more detailed answer (for another route): How to customize FOS UserBundle URLs

Override FOSUserBundle routes Symfony2

First of all the the yaml routes are not working because the FOSUserBundle Routes are defined in xml.
So your yaml routes won't imported.

here the FOSUserBundle Routes:
https://github.com/FriendsOfSymfony/FOSUserBundle/tree/master/Resources/config/routing

If the FOSUserBundle is the parent bundle of your userbundle you are able to rewrite the FOSUserBundle routing resources.
How to do this is explained here:
http://symfony.com/doc/current/cookbook/bundles/inheritance.html#overriding-resources-templates-routing-etc

Further more to answer to the last point how to pass the locale into the route is described here:
http://symfony.com/doc/current/cookbook/bundles/inheritance.html#overriding-resources-templates-routing-etc

<route id="contact" path="/{_locale}/contact">
<default key="_controller">AcmeDemoBundle:Contact:index</default>
<requirement key="_locale">%locales%</requirement>
</route>

Symfony2 FosUserBundle customize Login query

Create a class inside entity folder that extends FOS\UserBundle\Doctrine\UserManager (i'm assuming there is a class called siteConfig.php with a static University_id field updated by a db query)

<?php
namespace Example\Bundle\ExampleBundle\Entity

use FOS\UserBundle\Doctrine\UserManager as BaseUserManager;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use FOS\UserBundle\Util\CanonicalizerInterface;
use FOS\UserBundle\Model\UserInterface;
use Example\Bundle\ExampleBundle\siteConfig;

class UserManager extends BaseUserManager {
public function __construct(EncoderFactoryInterface $encoderFactory, CanonicalizerInterface $usernameCanonicalizer,
CanonicalizerInterface $emailCanonicalizer, EntityManager $em, $class) {

parent::__construct($encoderFactory, $usernameCanonicalizer, $emailCanonicalizer, $em, $class);

}
/**
* this overides the findUserByUsernameOrEmail in FOS\UserBundle\Doctrine\UserManager
**/
public function findUserByUsernameOrEmail($usernameOrEmail) {
if (filter_var($usernameOrEmail, FILTER_VALIDATE_EMAIL)) {
return $this->findUserBy(array('emailCanonical' => $this->canonicalizeEmail($usernameOrEmail), 'university' => siteConfig::$university_id));
}

return $this->findUserBy(array('usernameCanonical' => $this->canonicalizeUsername($usernameOrEmail), 'university' => siteConfig::$university_id));
}
}

Dependency injection for User manager, inside services.yml

ExampleUserManager:
class: namespace Example\Bundle\ExampleBundle\Entity\UserManager
arguments: [@security.encoder_factory, @fos_user.util.username_canonicalizer, @fos_user.util.email_canonicalizer, @fos_user.entity_manager, namespace Example\Bundle\ExampleBundle\Entity\User]

Inside config.yml add the following configuration under fos_user

service:
user_manager: ExampleUserManager

Inside security.yml under provider add the following

providers:
fos_userbundle:
id: fos_user.user_provider.username_email

FOS user /register path works in url but not as a path

According to @FOSUserBundle/Resources/config/routing/registration.xml the route is named fos_user_registration_register.

So {{ path('fos_user_registration_register') }} should work.

Edit user profile using FOS User Bundle

The registration event is fired in your method, this is why the newly created user is logged in automatically.

To avoid this comportment and keep the current user as logged in (don't authenticate the newly created user), remove the following line :

$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);

This two lines too :

$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);

And this line :

$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

Now you are just creating a new user without telling FOSUserBundle you are in registration.

Update

For the edit part, you have to create a specific method to reproduces the comportment of the editProfile, but for a given user (not the authenticated user).

Try to use the following :

public function editUserAction($id)
{
$user = $em->getRepository('YourBunde:User')->find($id);

if (!is_object($user)) {
throw new AccessDeniedException('This user does not have access to this section.');
}

/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.profile.form.factory');

$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);

if ($form->isValid()) {
/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$userManager->updateUser($user);

$session = $this->getRequest()->getSession();
$session->getFlashBag()->add('message', 'Successfully updated');
$url = $this->generateUrl('matrix_edi_viewUser');
$response = new RedirectResponse($url);

}

return $this->render('FOSUserBundle:Profile:edit.html.twig', array(
'form' => $form->createView()
));
}

And the route :

security_edit_profile:
path: /users/{id}/edit
defaults: { _controller: YourBundle:Security:editUser }

Symfony2 - FOSUserBundle set user entity field after registration

If I understand correctly, what you want to do is a slug with the firstname and lastname field.

First and last name to be used as slug must also be sanitizated to replace accented characters, spaces, etc..

To do everything automatically, you can use the Doctrine Extension, in particular Sluggable: https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/sluggable.md

This is an example using annotations for what you need:

<?php
// src/Acme/UserBundle/Entity/User.php

namespace Acme\UserBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

/**
* @ORM\Entity
* @ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\Column(length=64, unique=false)
*/
private firstname;

/**
* @ORM\Column(length=64, unique=false)
*/
private lastname;

/**
* @Gedmo\Slug(fields={"firstname", "lastname"}, separator="-")
* @ORM\Column(length=128, unique=true)
*/
private $slug;

public function __construct()
{
parent::__construct();
// your own logic
}

//... setter and getter...
}


Related Topics



Leave a reply



Submit