Submitting to database - symfony

I can't submit my form to database when I validate I have nothing in my table in phpMyAdmin. Here is the code in the controller. I want to submit a form which contains an upload type.
<?php
// src/AppBundle/Controller/ProductController.php
namespace Upload\FileBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Upload\FileBundle\Entity\Product;
use Upload\FileBundle\Form\ProductType;
use Symfony\Component\Form\FormView;
class ProductController extends Controller
{
/**
* #Route("/product/new", name="app_product_new")
*/
public function newAction(Request $request)
{
$product = new Product();
$form = $this->createForm(new ProductType(), $product);
$form->handleRequest($request);
if ($form->isValid()) {
// $file stores the uploaded PDF file
/** #var Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $product->getBrochure();
// Generate a unique name for the file before saving it
$fileName = md5(uniqid()).'.'.$file->guessExtension();
// Move the file to the directory where brochures are stored
$brochuresDir = $this->container->getParameter('kernel.root_dir').'/../web/uploads/brochures';
$file->move($brochuresDir, $fileName);
// Update the 'brochure' property to store the PDF file name
// instead of its contents
$product->setBrochure($fileName);
// ... persist the $product variable or any other work
return $this->redirect($this->generateUrl('app_product_list'));
}
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return $this->redirect($this->generateUrl('upload_file_success'));
}
return $this->render('UploadFileBundle:Product:new.html.twig', array(
'form' => $form->createView(),
));
}
}

Your logic is wrong.
Try this code:
<?php
// src/AppBundle/Controller/ProductController.php
namespace Upload\FileBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Upload\FileBundle\Entity\Product;
use Upload\FileBundle\Form\ProductType;
use Symfony\Component\Form\FormView;
class ProductController extends Controller
{
/**
* #Route("/product/new", name="app_product_new")
*/
public function newAction(Request $request)
{
$product = new Product();
$form = $this->createForm(new ProductType(), $product);
if ($request->isMethod(Request::POST))
{
$form->handleRequest($request);
if ($form->isValid()) {
// $file stores the uploaded PDF file
$file = $product->getBrochure();
/* #var Symfony\Component\HttpFoundation\File\UploadedFile $file */
// Generate a unique name for the file before saving it
$fileName = md5(uniqid()).'.'.$file->guessExtension();
// Move the file to the directory where brochures are stored
$brochuresDir = $this->container->getParameter('kernel.root_dir').'/../web/uploads/brochures';
$file->move($brochuresDir, $fileName);
// Update the 'brochure' property to store the PDF file name
// instead of its contents
$product->setBrochure($fileName);
// ... persist the $product variable or any other work
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return $this->redirect($this->generateUrl('app_product_list'));
}
}
return $this->render('UploadFileBundle:Product:new.html.twig', array(
'form' => $form->createView(),
));
}
}
I also recommend using VichUploaderBundle
https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/index.md

Because your logic is wrong. You check form in first if and redirect code to list page. But your code can not work second if ever.

Related

Bind an object to a Symfony form

I have a entity with some data prefilled, and I want to display them on the form : here state would be ACTIVE and customerId = 1;
// Form file (ben.file.create)
protected function buildForm()
{
$this->formBuilder->add('name', 'text', ['label'=>'Nom du patient'])
->add('customerId', 'integer')
->add('state', 'choice', ['choices'=>['ACTIVE'=>'ACTIVE',
'DONE'=>'DONE', 'CANCELLED'=>'CANCELLED']]);
}
// in the controller
public function index()
{
$form = $this->createForm("ben-file-create");
$file = new BenFile();
$file->setCustomerId(1);
$file->setState('ACTIVE');
$form->getForm()->submit($file); // <--- Here the glue problem
return $this->render('create-file', array());
}
It looks like submit is not the right bind function. I would expect that the form is pre-filled accordingly, and after the POST request, I have an updated BenFile entity.
You can do easily in createForm method :
// in the controller
public function index(Request $request)
{
$file = new BenFile();
$file->setCustomerId(1);
$file->setState('ACTIVE');
$form = $this->createForm("ben-file-create", $file);
// handle submit
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// flush entity
$fileNew = $form->getData();
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($fileNew );
$entityManager->flush();
}
return $this->render('create-file', array());
}

Symfony 4 - Good practice to remove your own user account while connected

I would like my users to be able to delete their own user account. I made a SecurityController where there is my 3 functions login, logout and deleteUser. When I delete the current user in database this error appears :
You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine.
When I delete another user, it works correctly because he's not connected.
Do I have to serialize the User and pass it through a Service, logout the user then remove it in a Service? Or can I clear the PHP session in the controller but I don't know how to do it with symfony4 I think it changed since version 4.
<?php
namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use App\Entity\User;
use App\Form\UserType;
class SecurityController extends Controller
{
/**
* #Route("/createAdmin", name="create_admin")
*/
public function createAdminUser(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
$user = new User();
$form = $this->createForm(UserType::class, $user, array(
'is_fresh_install' => true,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Encode the password
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
// save the User
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
// Do what you want here before redirecting the user
return $this->redirectToRoute('login');
}
return $this->render('security/register_admin_user.html.twig', array(
'form' => $form->createView(),
));
} else {
if ($this->getUser())
{
return $this->redirectToRoute('user_account');
} else {
return $this->redirectToRoute('login');
}
}
}
/**
* #Route("/login", name="login")
*/
public function login(Request $request, AuthenticationUtils $authUtils)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
return $this->redirectToRoute('create_admin');
} else {
$error = $authUtils->getLastAuthenticationError();
$lastUsername = $authUtils->getLastUsername();
return $this->render('security/login.html.twig', array(
'last_username' => $lastUsername,
'error' => $error,
));
}
}
/**
* #Route("/logout", name="logout")
*/
public function logout()
{
}
/**
* #Route("/delete_user/{id}", name="delete_user")
*/
public function deleteUser($id)
{
$em = $this->getDoctrine()->getManager();
$usrRepo = $em->getRepository(User::class);
$user = $usrRepo->find($id);
$em->remove($user);
$em->flush();
return $this->redirectToRoute('user_registration');
}
}
SOLUTION :
You have to clear the Session before deleting user entry in DB with this method:
<?php
use Symfony\Component\HttpFoundation\Session\Session;
// In your deleteUser function...
$currentUserId = $this->getUser()->getId();
if ($currentUserId == $id)
{
$session = $this->get('session');
$session = new Session();
$session->invalidate();
}
I don't know why $this->get('session')->invalidate(); doesn't work directly... if someone knows :)
I find it also a good solution to do this what is an accepted answer but you can also simply redirect the user to the logout route.
This has worked for me without any problem in Symfony 4.4
I think you have to serialize the User and pass it through a service.Just check with the previous versions,you will find out the problem.

How to load 'isSubmitted()-method' (defined in service controller) into the main controller?

I've put a registration form in a method so, that I can use it in different places.
My service registration controller looks like this:
public function loadRegisterForm()
{
$user = new User();
$form = $this->createForm(RegistrationType::class, $user);
$form->handleRequest($this->request);
$errors = "";
if ($form->isSubmitted())
{
if ($form->isValid())
{
$password = $this->get('security.password_encoder')
->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$user->setIsActive(1);
$user->setLastname('none');
$user->setCountry('none');
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
}
else
{
$errors = $this->get('validator')->validate($form);
}
}
$parametersArray['form'] = $form;
$parametersArray['errors'] = $errors;
return $parametersArray;
}
services.yml looks like this:
register_form_service:
class: ImmoBundle\Controller\Security\RegistrationController
calls:
- [setContainer, ["#service_container"]]
And the main controller where I load the service controller:
private function indexAction()
{
/**
* Load register form
*/
$registerForm = $this->get('register_form_service');
$registerParameters = $registerForm->loadRegisterForm();
$registerParameters['form']->handleRequest($request);
return $this->render(
'ImmoBundle::Pages/mainPage.html.twig',
array(
'register_form' => $registerParameters['form']->createView(),
'errors' => $registerParameters['errors'],
)
);
}
The form itself is well rendered, so there is no problem. However nothing happens if I try to submit the form. I know that I should add the following line to the main controller
if ($registerParameters['form']->isSubmitted())
{
// add to db
}
But is there any way to do it only in a service controller?
You do not need a service definition to inject the container into your controller. If the controller extends Symfony\Bundle\FrameworkBundle\Controller\Controller all services are accesible via ->get(). Next to that, $form->isValid() already checks whether the form is submitted.
Why is your action private? It should be public, and it need to get the Request object as it's first parameter:
public function indexAction(Request $request)
{
$user = new User();
$form = $this->createForm(RegistrationType::class, $user);
$form->handleRequest($request);
if ($form->isValid()) {
// Do something here
}
}
See http://symfony.com/doc/current/book/forms.html#handling-form-submissions

Symfony2.6 - Service

I have learnt Symfony2 since several months.
I have created a service. When I use it in a simple controller, I have no problem. When I use it in my controller that manages my entity, I have a problem.
My service is:
<?php
namespace Cours\BlogBundle\Services;
class Service1
{
public function creerSlug($texte)
{
$texte = transliterator_transliterate("Latin-ASCII; [:Punctuation:] Remove; Lower();", $texte);
$texte = preg_replace('/[-\s]+/', '-', $texte);
$texte = trim($texte, '-');
return $texte;
}
}
My simple controller is:
<?php
namespace Cours\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Cours\BlogBundle\Services\Service1;
class TestController extends Controller
{
public function indexAction()
{
$texte = "Le test du slug";
$service1 = $this->container->get('service1');
$texte = $service1->creerSlug($texte);
return $this->render('CoursBlogBundle:Test:index.html.twig', array('texte' => $texte));
}
}
The action of my controller that manages my entity is:
public function ajouterAction(Request $request)
{
$rubrique = new Rubrique();
$form = $this->createForm(new RubriqueType(), $rubrique);
if ($request->isMethod('POST'))
{
$form->handleRequest($request);
if ($form->isValid())
{
$manager = $this->getDoctrine()->getManager();
$rubrique = $form->getData();
$texte = $rubrique->getTexte();
$service1 = $this->container->get('service1');
$slug = $serviceSlug->creerSlug($texte);
$slug = $rubrique->setSlug($slug);
$manager->persist($rubrique);
$manager->flush();
return $this->redirect($this->generateUrl('cours_blog_accueil'));
}
}
return $this->render('CoursBlogBundle:Rubrique:ajouter.html.twig', array('form' => $form->createView()));
}
My view tells me that my slug can’t be empty.
I think there is a mistake in my action but I can’t find it.
Does anyone help me?
KISSES AND THANK YOU VERY MUCH
change
$service1 = $this->container->get('service1');
$slug = $serviceSlug->creerSlug($texte);
to
$serviceSlug = $this->container->get('service1');
$slug = $serviceSlug->creerSlug($texte);
I suggest to comment/remove $rubrique = $form->getData(); $texte = $rubrique->getTexte(); from ajouterAction and set the text manually (just for testing purpose):
if ($form->isValid())
{
$manager = $this->getDoctrine()->getManager();
// $rubrique = $form->getData();
// $texte = $rubrique->getTexte();
$rubrique->setTexte('Some text');
$service1 = $this->get('service1');
$slug = $service1->creerSlug($rubrique->getTexte());
...
if it works, you can set some validations to the texte field in your form type which prevents entering an invalid value.
Also I suggest to use some libraries (Cocur/Slugify can be a good option) instead of handling the process by yourself.

symfony2: trying to render a form in the template

I'm trying to render a form that I've just generated from an entity, but Im getting the error below...
<?php
namespace Prueba\FrontendBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Prueba\FrontendBundle\Form\ItemType;
class DefaultController extends Controller
{
/**
* #Route("/hello")
* #Template()
*/
public function indexAction($name)
{
$form = new ItemType();var_dump(get_class($form));
return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
'form' => $form->createView(),
));
}
}
string(35) "Prueba\FrontendBundle\Form\ItemType" Fatal error: Call to
undefined method Prueba\FrontendBundle\Form\ItemType::createView() in
/home/javier/programacion/sf2000/src/Prueba/FrontendBundle/Controller/DefaultController.php
on line 20
Change
$form = new ItemType();
to
$form = $this->createForm(new FormType());
And if you want to attach an empty entity to the form (easier validation and form processing):
$item = new Item();
$form = $this->createForm(new FormType(), $item);

Resources