Symfony2 - FOSUserBundle set user entity field after registration - php

I have a user entity with firstname,lastname and url attributes, extending the FOSUserBundle User. I want to store in the url attribute the value of fistname and lastname as one strig.
Some people suggested that i should use a listener and a service, so i 've made:
The event seems to work after registration, but i can't find a way to change my user url...
servises.yml
services:
kernel.listener.RegistrationListener:
class: Apana\Bundle\MainBundle\EventListener\RegistrationListener
tags:
- { name: kernel.event_listener, event: fos_user.registration.completed, method: onUserRegistration }
And in RegistrationListener.php :
<?php
namespace Apana\Bundle\MainBundle\EventListener;
use Apana\Bundle\MainBundle\Entity\User;
use Symfony\Component\Security\Core\SecurityContext;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\UserEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
class RegistrationListener
{
public function onUserRegistration()
{
$user = new User();
$ap= = $user->getFirstname();
echo($ap);exit();
}
}

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...
}

Why you don't use UserManager for that instead of a listener? I would override the FOSUser register with my own and do something like:
$userManager = $this->container->get('fos_user.user_manager');
$user = $userManager->createUser();
$user->setUrl("any data");
It's more easy and less complicated at least for me

Ok, i 've solved my problem with an eventlistener and the FOSUserBundle UserEvent
<?php
namespace Apana\Bundle\MainBundle\EventListener;
use FOS\UserBundle\Event\UserEvent;
class RegistrationListener
{
public function onUserRegistration(UserEvent $event)
{
$user = $event->getUser();
$url = strtolower($user->getFirstname().".".$user->getLastname());
$user->setUrl($url);
}
}

Related

symfony 5 , Doctrine Lifecycle Listeners not running

I try a Doctrine Lifecycle Listeners create but he don't execute the dump.
i have created a entity, a listener and update service.yml
it's crazy ;-)
i have:
in services.yaml
App\EventListener\TestOrmListener:
tags:
- { name: doctrineormtester,event: postPersist, entity: 'App\Entity\Galery'}
in src/EventListener/TestOrmListener.php
<?php
namespace App\EventListener;
use App\Entity\Galery;
use Doctrine\Persistence\Event\LifecycleEventArgs;
class TestOrmListener
{
// the listener methods receive an argument which gives you access to
// both the entity object of the event and the entity manager itself
public function postPersist(LifecycleEventArgs $args): void
{
$entity = $args->getObject();
// if this listener only applies to certain entity types,
// add some code to check the entity type as early as possible
if (!$entity instanceof Galery) {
return;
}
$entityManager = $args->getObjectManager();
dump($entityManager);
die('mick');
// ... do something with the Product entity
}
}
an in the Entity Galery
<?php
namespace App\Entity;
use App\Repository\GaleryRepository;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\Traits\Timestampable;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass=GaleryRepository::class)
* #ORM\HasLifecycleCallbacks
*/
class Galery
{
use Timestampable;
/**
* #ORM\Id
* #Assert\NotBlank
* #ORM\Column(type="string", length=255)
*/
private $nom;
Do you have a idea?
You have a problem in your tag section.
According to the official documentation:
The next step is to enable the Doctrine listener in the Symfony application by creating a new service for it and tagging it with the doctrine.event_listener tag
So your service definition should look like this:
App\EventListener\TestOrmListener:
tags:
- { name: 'doctrine.event_listener', event: 'postPersist', entity: 'App\Entity\Galery' }

Symfony / Doctrine EntityListener doesn't work

I've a problem with an EntityListener... My EntityListener is not called, he doesn't work and I don't know why ! I use Symfony 3.4 and Doctrine 2.5.
So, my Entity :
<?php
namespace TelecomlineBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* LigneTelecom
*
* #ORM\Table(name="LIGNETELECOM")
* #ORM\Entity(repositoryClass="TelecomlineBundle\Repository\LigneTelecomRepository")
* #ORM\EntityListeners({"TelecomlineBundle\Doctrine\Listener\LigneTelecomListener"})
*/
class LigneTelecom
{
// etc ...
}
My EntityListener :
<?php
namespace TelecomlineBundle\Doctrine\Listener;
use TelecomlineBundle\Entity\LigneTelecom;
use TelecomlineBundle\Service\myService;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;
class LigneTelecomListener
{
/** #var myService $myService */
private $myService;
public function __construct(myService $myService)
{
$this->myService = $myService;
}
/**
* #ORM\PostUpdate()
*
* #param LigneTelecom $ligneTelecom
* #param LifecycleEventArgs $eventArgs
*/
public function postUpdate(LigneTelecom $ligneTelecom, LifecycleEventArgs $eventArgs)
{
$this->myService->calculate($ligneTelecom);
}
// etc ...
My service.yml :
telecomline.doctrine.lignetelecom_listener:
class: "TelecomlineBundle\Entity\LigneTelecom"
arguments: ["#telecomline.porte"]
tags:
- { name: doctrine.orm.entity_listener }
If anyone have a solution, I block on that since 3 hours :'(
you should specify which events subscriber wants to listen to
you use long form of definition or inherit from EventSubscriber and override getSubscribedEvents
The Symfony doc is not correct. You don't need a config in services.yaml. Just put an annotation to the entity class like shown on Doctrine docs.
<?php
namespace MyProject\Entity;
use App\EventListener\UserListener;
#[Entity]
#[EntityListeners([UserListener::class])]
class User
{
// ....
}

Symfony 3.4/Doctrine 2 one-to-one association error

I have two entities - User and Cart. They're supposed to have a one-to-one association, created by the following:
User.php:
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\OneToOne(targetEntity="Cart", mappedBy="user")
*/
private $cart;
// other things not related to the association
}
Cart.php:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Class Cart
* #package AppBundle\Entity
*
* #ORM\Entity
* #ORM\Table(name="Cart")
*/
class Cart
{
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="cart")
*/
private $user;
// other things not related to the association
}
I create the cart and persist all entities when someone attempts to view their cart for the first time:
CartController.php:
public function showCartAction()
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$user = $this->getUser();
$cart = $user->getCart();
if ($cart) {
$items = $cart->getCartItems();
} else {
$cart = new Cart();
$user->setCart($cart);
$em = $this->getDoctrine()->getManager();
$em->persist($cart);
$em->persist($user);
$em->flush();
$items = $cart->getCartItems();
}
// other unrelated things in the controller
}
With this, carts are created, but there's no association between User and Cart:
user_id should have the user's id.
Any ideas on why this isn't working? And is it possible to simply do something like:
public function __construct()
{
$this->cart = new Cart();
}
In my User entity? Would that enforce the association? Or is that the wrong way to go?
You probably want to ensure that a cart can not bet created without a user being associated with it. Unlike fields, associations are nullable by default. You have to add a JoinColumn annotation for this.
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="cart")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
The other thing is that since you have a bi-directional association you have to make sure that when calling $user->setCart($cart) this will also add the user to the cart, e.g. like this:
public function setCart(Cart $cart): void
{
$this->cart = $cart;
$cart->setUser($this);
}
Since the cart can not be created without a user you could also make the user a constructor argument instead:
public function __construct(User $user)
{
$this->user = $user;
$user->setCart($this);
}
This way you can omit the setUser() method on the cart ensuring that no one switches the cart owner by accident.
With the latter one you might not even have to link back to the user, since the cart is the owning side, but to ensure that both entities have a consistent state I would always do this, when you have a bi-directional association.

Sylius customizing model dose not working

It's my class file Country.php
<?php
namespace App\Entity;
use Sylius\Component\Addressing\Model\Country as BaseCountry;
class Country extends BaseCountry {
/**
* #var bool
*/
private $flag;
/**
* #return bool|null
*/
public function getFlag(): ?bool {
return $this->flag;
}
/**
* #param bool $flag
*/
public function setFlag(bool $flag): void {
$this->flag = $flag;
}
}
It's my orm file. AppBundle/Resources/config/doctrine/Country.orm.yml
App\Entity\Country:
type: entity
table: sylius_country
fields:
flag:
type: boolean
nullable: true
It's my config file. config/_sylius.yml
sylius_addressing:
resources:
country:
classes:
model: App\Entity\Country
It's all ok like sylius customizing model but it's not working.
It's my orm file. AppBundle/Resources/config/doctrine/Country.orm.yml
The orm file should be placed at src\Resources\config\doctrine for v1.3
Also, what's the result of php bin/console debug:config sylius_addressing?
//2018-12-18
Maybe try:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Addressing\Model\Country as BaseCountry;
/**
* Class Country
* #package App\Entity
* #ORM\Table(name="sylius_country")
* #ORM\Entity
*/
class Country extends BaseCountry {
type: mappedSuperclass in doctrine mapping
Make sure AppBundle extends AbstractResourceBundle
Make sure AppBundle has protected $mappingFormat = ResourceBundleInterface::MAPPING_YAML;

FOSUserBundle (Symfony2). I have some questions

1) How can I add new fields in table and in registration action (show new fields on reg page)? For example: I want to add new fields last_name, age.
2) I added new listener for REGISTRATION_COMPLETED
/src/Acme/UserBundle/EventListener/RegistrationCompletedListener.php:
<?php
namespace Acme\UserBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Listener
*/
class RegistrationCompletedListener implements EventSubscriberInterface
{
private $router;
public function __construct(UrlGeneratorInterface $router)
{
$this->router = $router;
}
/**
* {#inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_COMPLETED => 'onRegistrationCompletedSuccess',
);
}
public function onRegistrationCompletedSuccess(FormEvent $event)
{
$url = $this->router->generate('homepage');
$event->setResponse(new RedirectResponse($url));
}
}
/src/Acme/UserBundle/Resources/config/services.yml:
services:
acme_user.registration_completed:
class: Acme\UserBundle\EventListener\RegistrationCompletedListener
arguments: [#router]
tags:
- { name: kernel.event_subscriber }
Why don't work?
1) You should extend Base User class and add there your new fields, like this:
namespace Your\CustomBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #var string
*
* #ORM\Column(name="first_name", type="string", length=255)
*/
private $firstName;
/**
* #var string
*
* #ORM\Column(name="last_name", type="string", length=255)
*/
private $lastName;
}
And update appconfig/config.yml:
#FOSLUserBundle Configuration
fos_user:
user_class: Your\CustomBundle\Entity
Then you need extend and configure new registration form. Here is a link how you can do that.
[Edit]:
2)
Create event listener like this:
namespace Your\Bundle\EventListener;
use FOS\UserBundle\Event\FilterUserResponseEvent;
class UserListener
{
public function onRegistrationCompleted(FilterUserResponseEvent $event){
$user = $event->getUser();
//do sth....
}
}
And register service for that:
services:
some_name.security.registration_listener:
class: Your\Bundle\EventListener\UserListener
tags:
- { name: kernel.event_listener, event: fos_user.registration.completed, method: onRegistrationCompleted }

Categories