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 }
Related
product_show:
path: /product/{id}
controller: App\Controller\ProductController::show
methods: GET
requirements:
id: \d+
<?php
declare(strict_types=1);
namespace App\Entity;
use App\Repository\ProductRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=ProductRepository::class)
*/
class Product
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #ORM\Column(type="integer")
*/
private int $id;
/**
* #ORM\Column(type="boolean", options={"default": true})
*/
private bool $active = true;
public function getId(): int
{
return $this->id;
}
public function active(): bool
{
return $this->active;
}
}
<?php
namespace App\Controller;
use App\Entity\Product;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class ProductController extends AbstractController
{
public function show(Product $product): Response
{
return $this->render('product/show.html.twig', [
'product' => $product,
]);
}
}
When $product->active() return false, I want to send 404 response.
But it should be done without adding an if in controller action.
Perhaps I should modify something in ParamConverter. How can I do this? How can I overwrite ParamConverter behavior?
You can fetch via an Expression and use a custom function in your repository.
For example:
class ProductController extends AbstractController
{
/**
* #Route("/product/{product_id}")
* #Entity("product", expr="repository.findOneActive(product_id)")
*/
public function show(Product $product): Response
{
return $this->render('product/show.html.twig', [
'product' => $product,
]);
}
}
And in your ProductRepository:
class ProductRepository
{
public function findOneActive($productId)
{
// your query here...
}
}
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
{
// ....
}
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;
I am trying to create my own service with a custom constraint and its validator.
MailAlert Entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Validator\AntiBadMail;
/**
* MailAlert
*
* #ORM\Table(name="mail_alert")
* #ORM\Entity(repositoryClass="AppBundle\Repository\MailAlertRepository")
* #UniqueEntity(fields="mail", message="Cette adresse a déjà été enregistrée.")
*/
class MailAlert
{
/**
* #var string
*
* #ORM\Column(name="Mail", type="string", length=255)
* #Assert\Email
* #AntiBadMail()
*/
private $mail;
}
AntiBadMail Constraint:
namespace AppBundle\Validator;
use Symfony\Component\Validator\Constraint;
/**
* #Annotation
*/
class AntiBadMail extends Constraint
{
public function validatedBy()
{
return 'app.validator_antibadmail'; // Ici, on fait appel au service
}
}
AntiBadMailValidator:
namespace AppBundle\Validator;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class AntiBadMailValidator extends ConstraintValidator
{
private $requestStack;
private $em;
public function __construct(RequestStack $requestStack, EntityManagerInterface $em)
{
$this->requestStack = $requestStack;
$this->em = $em;
}
public function validate($value, Constraint $constraint)
{
$request = $this->requestStack->getCurrentRequest();
$mail = $request->request->all()['form']['mail'];
$listPiecesOfMail = explode("#", $mail);
$mailBefore = $listPiecesOfMail[0];
$mailAfter = $listPiecesOfMail[1];
$ListAcceptedMails = $this->container->getParameters('listAcceptedMails');
if(count($mailBefore)<3){
$this->context->addViolation($constraint->messageBefore);
}
if(!preg_match('#'.implode('|',$ListAcceptedMails).'#', $mailAfter)){
$this->context->addViolation($constraint->messageAfter);
}
}
}
Service Configuration:
app.validator_antibadmail:
class: AppBundle\Validator\AntiBadMailValidator
arguments:
- "#request_stack"
- "#doctrine.orm.entity_manager"
I don't know why but I get the error than my validator doesn't exist. I use the validatedBy(), and give it the proper name.
I am lost. Can you help me ?
EDIT : This is the error :
Constraint validator "app.validator_antibadmail" does not exist or it is not enabled. Check the "validatedBy" method in your constraint class "AppBundle\Validator\AntiBadMail".
For anyone still facing this issue, this is how you configure your Validator service with Symfony 3.4:
AppBundle\Validator\Constraints\CustomValidator:
public: true
class: AppBundle\Validator\Constraints\CustomValidator
autowire: true
tags: [{ name: validator.constraint_validator, alias: app.validator.custom }]
Everything else should be done as described in the question.
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);
}
}