I have a Symfony project with FOSUserBundle, i extended the FormType in my personal Bundle following this guide "http://symfony.com/doc/master/bundles/FOSUserBundle/overriding_forms.html"
I created a Person entity with first name, last name, adresse ..., created its FormType like this :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('firstName', TextType::class)
->add('lastName', TextType::class)
->add('adress', TextType::class)
->add('account', AccountType::class) ;
}
The Account entity is the user class for FOSUserBundle
Then i generated the CRUD for Person, the newAction() looks like this :
public function newAction(Request $request)
{
$person = new Person();
$form = $this->createForm('AppBundle\Form\PersonType', $person);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$person->getAccount()->setEnabled(1); //i'm doing this because it's not automatic
$em->persist($person->getAccount());
$em->persist($person);
$em->flush($person);
return $this->redirectToRoute('fos_user_security_login'); // redirecting to the login page because it's not done automatically
}
return $this->render('person/new.html.twig', array(
'person' => $person,
'form' => $form->createView(),
));
}
The two entitys have a OneToOne relationship, with this code they are both persisted in the data base and i can use the username and password to log in normally
Here is my FOSUerBundle configuration :
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\Account
from_email:
address: "%mailer_user%"
sender_name: "%mailer_user%"
registration:
form:
type: AppBundle\Form\AccountType
I want to the user to log in automatically after registration like it happens when using the default FOSUserBundle registration, anyone got an idea how to do so ?
I tried a lot of stuff but no success
Thanks for your answers
I was able to login from my controller using the $person->getAccount() object:
All i have to do is dispatch the REGISTRATION_COMPLETED event like in the default Controller : https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/RegistrationController.php#L78
Just copied some code to my controller
This will trigger the authentication : https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/EventListener/AuthenticationListener.php
Related
I have installed the packages Google-mailer, doctrine -fixtures-bundle, and webpack-bundle. I'm at the beginning of this project and there to create the first controller which should have a form to login. Controller and From were created with the commands bin/console make: controller and make: form, and not changed. But I already have a problem because I get an error when I call the form
Failed to start the session: already started by PHP.
I can explain this message with the fact that when creating the view Symfony tries to start a session because the form is protected with csrf (which should stay that way). But this should not be a problem because Symfony manages the sessions.
php.ini => session.auto_start=0;
framework.yaml:
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
#http_method_override: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
#esi: true
#fragments: true
php_errors:
log: true
Test function in HomeController:
/**
* #Route("/testform", name="testform", methods={"GET","POST"})
*/
public function testform()
{
$User = new User();
$form = $this->createForm(TestFormType::class, $User);
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->redirectToRoute('home');
}
return $this->render('home/testform.html.twig', [
'form' => $form->createView(),
]);
}
TestFormType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email')
->add('forname')
->add('name')
->add('password');
}
I have a Form Type that uses a query builder with an entity field to get related options. But because I am using a custom entity manager for the entity it doesnt seem to recognize those options. And i get the error:
Entities passed to the choice field must be managed. Maybe persist them in the entity manager?
The controller action:
/**
* #Route("/edit/{keyword_rank_id}/", name="lg.keywordrank.campaign.edit")
* #Template
*/
public function editAction(Request $request, Company $company, $client_slug, $keyword_rank_id)
{
$em = $this->getDoctrine()->getManager($company->getEntityManagerName());
$client = $this->getEntityOrNotFound($em, 'LGClientBundle:Client', 'client_slug', $client_slug);
$kr = $this->getEntityOrNotFound($em, 'LGKeywordRankBundle:KeywordRank', 'keyword_rank_id', $keyword_rank_id);
$form = $this->createForm(new KeywordRankForm(), $kr, array('client'=>$client,'em'=>$em));
...
}
And the Form Type:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name','text',array(
'label'=>'Campaign Name'
))
->add('client_domain', 'entity', array(
'class' => 'LGClientBundle:ClientDomain',
'choices'=> $this->getClientDomains($options['em'], $options['client']),
'property' => 'domain',
'label' => 'Domain: '
));
}
private function getClientDomains($em, $client)
{
$domains = $em->getRepository('LGClientBundle:ClientDomain')->findBy(array('client'=>$client));
return $domains;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'LG\KeywordRankBundle\Entity\KeywordRank',
'client' => null,
'em' => null
));
}
public function getName()
{
return 'lg_project_keywordrank';
}
Anyone have a similar issue or know how to resolve this would be great
You can specify the entity manager to use when you add a field:
->add('client_domain', 'entity', array(
'class' => 'LGClientBundle:ClientDomain',
'choices'=> $this->getClientDomains($options['em'], $options['client']),
'em' => $options['em'],
'property' => 'domain',
'label' => 'Domain: '
));
This option takes the entity manager name, not the option itself, so you have to change
$em = $this->getDoctrine()->getManager($company->getEntityManagerName());
into
$em = $company->getEntityManagerName();
Check out the doc here: http://symfony.com/doc/current/reference/forms/types/entity.html#em
I had the same issue on my app and in fact if I pass entity manager instance to form it works.
In my case the issue was rather in config.yml file and I wanted to solve this globaly.
I have as default entity manager, "mymodule" but in FormType was used different entity manager.
This was my configuration
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: mymodule
entity_managers:
mymodule:
auto_mapping: true
connection: mymodule
mappings:
AppBundle: ~
XBundle: ~
When I changed default_entity_manager to default in my config file:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: default
entity_managers:
default:
connection: mymodule
mappings:
AppBundle: ~
XBundle: ~
and I changed in my controller:
$em = $this->getDoctrine()->getManager('mymodule');
to:
$em = $this->getDoctrine()->getManager('default');
It works without passing entity manager to FormType so in my case it's about orm entity manager configuration.
im looking for a way to set flash message in admin controller of sonata admin bundle, they allow to set flash messages in CRUDController as
$this->get('session')->setFlash('sonata_flash_error', 'flash_batch_merge_error');
but not in the Admin Controller,
this is my admin contrller
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
class ConfigAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('System Settings')
->add('Name','text', array('label' => "Configuration Name"))
->add('Language', 'choice', array(
'label' => 'System Language',
'choices' => array(0 => 'English', 1 => 'Swedish'),
'preferred_choices' => array(0),
))
->add('commonmail','text', array('label' => "Common e-Mail"))
->add('dateformat','text', array('label' => "Date format"))
->add('currencyformat','text', array('label' => "Currency format"))
->end()
}
public function postUpdate($object) {
// here i need to perform some validations and set flash message if there is an errror
}
}
appreciate your help
Yes, you can set a flash message in an admin class. First, you can define a custom flash message type for the SonataCoreBundle. For example, if you want a success flash message type, add this in the app/config/config.yml file:
sonata_core:
flashmessage:
success:
types:
- { type: mytodo_success, domain: MyToDoBundle }
Then, you need to know when to set the message. For example, if you want to set the message after creating a new entity, you can do so overriding the postPersist function in your admin class, and adding the message in the Symfony flash bag:
public function postPersist($object) {
$this->getRequest()->getSession()->getFlashBag()->add("mytodo_success", "My To-Do custom success message");
}
This way, the message will be displayed whenever you create a new entity at the admin class.
You can also use the default type success:
public function postPersist($object) {
$this->getRequest()->getSession()->getFlashBag()->add("success", "My To-Do custom success message");
}
Because it is an Admin class I get the flashbag over the Session service:
protected function whereever()
{
$this->getFlashBag()->add(
'info',
'Your message'
);
}
...
protected function getFlashBag()
{
return $this->getConfigurationPool()->getContainer()->get('session')->getFlashBag();
}
Cheers
You are talking about an admin class, not a controller.
And this is not possible by default. Best way to do this is to write a custom CRUDController (extend from default one) and handle it there.
You need to inject the session service into your admin class.
http://symfony.com/doc/current/book/service_container.html#referencing-injecting-services
I use FOSUserBundle with a custom registration form that extends the one provided by the bundle. I want to override the validation so it doesn't check for a username (I generate it). I have read that this can be achieved thru the usage of validation groups.
These are the relevant parts of my form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
...
$builder->remove('username');
...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Ysu\Bundle\SiteBundle\Entity\User',
'validation_groups' => array('my-registration-group'),
'cascade_validation' => true
));
}
...
However the username is still validated with the validation files provided by the bundle. I found out that $options (array) contains an array validation_groupswhich in its turn contains the 'Registration' group, so that is why the field is still validated. However, I don't know how to remove it. If I unset it from $optionsbefore passing it to parent::buildFormit will still contain the Registration group.
Does anyone know how to solve this?
Turns out you can configure the validation groups for the FOSUserBundle's forms in config.yml:
fos_user:
....
registration:
form:
validation_groups: [default, registration_mod]
....
I am attempting to override the RegistrationFormType in the Symfony2 FOSUserBundle. I am following the documentation and believe i've covered everything. I've created a bundle to contain my overrides to the FOSUserBundle and the following code is from this bundle as well as the application config.
Has anyone experienced this when overriding FOSUserBundle, or see anything in my code that would help explain why I keep getting this error.
I'm on symfony v2.0.4
RegistrationFormType.php
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Thrive\SaasBundle\Form\Type;
use Symfony\Component\Form\FormBuilder;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('firstname', null, array('error_bubbling' => true))
->add('lastname', null, array('error_bubbling' => true))
->add('company', null, array('error_bubbling' => true))
->add('email', 'email', array('error_bubbling' => true))
->add('username', null, array('error_bubbling' => true))
->add('plainPassword', 'repeated', array('type' => 'password', 'error_bubbling' => true))
;
}
public function getName()
{
return 'thrive_user_registration';
}
}
Services.yml
services:
thrive_saas_registration.form.type:
class: Thrive\SaasBundle\Form\Type\RegistrationFormType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: thrive_user_registration}
Application's Config File
fos_user:
...
registration:
form:
type: thrive_user_registration
Turns out my services.yml file wasn't being loaded via dependency injection. After digging around i realized my extension.php file for this bundle was named incorrectly. Early on I had renamed the bundle and made a typo when renaming the extension.php file inside the DependencyInjection folder. After correcting the mispelling everything works again.
Did you tried to just add one new field and look if it works?
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
// add your custom field
$builder->add('name');
}
Also remember to clear your prod cache if you're testing from there...