Insert data from form to database - symfony

What i want to do is next:
Create simple form with FormBuilder
When form is submitted the result to be saved into database for particular user ( based on its ID )
In addition is the code from the controller:
public function helloAction(Request $request, $id){//displaying individual results for particular user//
// find the username which was in the view//
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery('SELECT b FROM AcmeWebBundle:baza b WHERE b.id = :id' )
->setParameter('id',$id);
$total = $query->getResult();
$baza = new baza ();
$em = $this->getDoctrine()->getManager();
$em->persist($baza);
$form = $this->createFormBuilder($baza)
->add ('rating','choice',array('label'=>'TEST44','choices'=>array(
'1'=>'1',
'2'=>'2',
'3'=>'3',
'4'=>'4'
),
'expanded'=>true,
'multiple'=>false
))
->getForm();
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
// perform some action, such as saving the task to the database
$em->flush();
return new Response('<h1>THANKS FOR Your feedback !!!!</h1>');
}
}
return $this->render('AcmeWebBundle:Default:hello.html.twig',array('all'=>$total,'id'=>$id ,'form'=>$form->createView()));
}
}
But this creates new row in the database, and add value only for the rating column.Moreover, id field,username and etc.. are empty.
What i want to do is, rating to be added for the colum rating, but for specific ID.

In the following example I create a form, get the data on POST and then persist the fresh object or a modified one, there is no point in persisting an empty object.
public function historialAction(Request $request)
{
$form = $this->createFormBuilder()
->add('phone', 'text', array('attr' => array('autofocus' => '')))
->add('period', 'number', array('attr' => array('value' => '12')))
->getForm();
if ($request->isMethod('POST')) {
$form->bind($request);
// data is an array with "phone" and "period" keys
$data = $form->getData();
$em = $this->getDoctrine()->getManager();
$contract = $em->getRepository('FrontBundle:Contract')->getContractByPhone($data["phone"]);
$contract->setOwner("John Doe");
$contract->setPhone($data["phone"]);
// or this could be $contract = new Contract("John Doe", $data["phone"], $data["period"]);
$em->persist($contract); // I set/modify the properties then persist
}

You could set the rating to the user entity like so..
if ($form->isValid())
$rating = $form->get('rating')->getData();
$user->setRating($rating);
// Assuming $user is the user entity
// etc..

Related

Binding entities to query parameters only allowed for entities have an identifier

I am using a Symfony 4 project, and I want to change the user password, so I created a method in my repository and called it to the controller, but this error it diplay to me,
Binding entities to query parameters only allowed for entities that have an identifier.
Repository
public function updateU($password,$email): ?Utilisateur
{
$dql = <<<DQL
SELECT u
FROM App\Entity\Utilisateur u
WHERE u.email = :email
AND u.password = :password
DQL;
return $this->getEntityManager()->createQuery($dql)
->setParameters(['email' => $email, 'password' => $password])
->getSingleScalarResult();
}
Controller
/**
* #Route("/Reset", name="Reset")
* Method({"GET"})
*/
public function New(
Request $request,
UtilisateurRepository $URe,
UserPasswordEncoderInterface $userPasswordEncoder,
EntityManagerInterface $entityManager,
MailerInterface $mailer
) {
$o = '';
$Varmail = $_GET['email'];
$user = new Utilisateur($o);
$form = $this->createFormBuilder($user)
->add('password', PasswordType::class)
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$to = $Varmail;
$sujet = 'Password Changed';
$Message = "Bonjour $Varmail Votre email est changé !";
$pass = $user->setPassword(
$userPasswordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
$URe->updateU($pass, $Varmail);
$Mai = new MailerController();
$Mai->sendEmail($mailer, $to, $sujet, $Message);
}
return $this->render('modifier_mdp/index.html.twig', [
'form' => $form->createView(),
]);
}
How can i solve it , And Thanks
In your updateU method, you are making a request to get, not update the data. It's better to use the ObjectManager to save the data, since you still have a updated instance of the Utilisateur object in the $user variable.
$user = $this->getDoctrine()->getManager()->getRepository(Event::class)->findOneBy(['email'=>$Varmail]);
$form = $this->createFormBuilder($user)->add('password', PasswordType::class)->getForm();
if ($form->isSubmitted() && $form->isValid()) {
// ...
$user->setPassword(
$userPasswordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
// save Utilisateur with new password
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
}

Retrieve session value and pass to an entity attribute

I want to retrieve a quantity for each item that I store in session and store it in database.
How do I retrieve the quantity in session and passed to my quantity attribute of my article entity during database persistence?
For example for this article:
(id 4, quantity 2).
I would store 2 in the quantity attribute of my article entity.
I tried :
$article->setQuantity($session->get('panier'));
I have this error:
An exception occurred while executing 'INSERT INTO article ....... {"4": "2"}
Notice: Array to string conversion
/**
* #Route("/payment", name="payment")
*/
public function paymentAction(Request $request)
{
$session = $request->getSession();
$produits = $this->getDoctrine()->getManager()->getRepository('AppBundle:Stock')->findArray(array_keys($session->get('panier')));
$commande = $session->get('commande');
var_dump($session->get('panier'));
if ($request->isMethod('POST')) {
$token = $request->get('stripeToken');
\Stripe\Stripe::setApiKey($this->getParameter("private_key"));
\Stripe\Charge::create(array(
"amount" => $commande->getTotal() * 100,
"currency" => "EUR",
"source" => $token,
"description" => ""
));
foreach ($produits as $produit) {
$article = new Article();
$article->setTitle($produit->getStock()->getTitle());
$article->setContent($produit->getStock()->getContent());
//problem here
$article->setQuantity($session->get('panier'));
//
$article->setPrice($produit->getPrice());
$commande->addArticle($article);
$em = $this->getDoctrine()->getManager();
$em->persist($commande);
$em->flush();
}
return $this->redirectToRoute('confirmation');
}
return $this->render(':default:payment.html.twig', array(
'commande' => $commande,
'panier' => $session->get('panier'),
'produits' => $produits,
'public_key' => $this->getParameter("public_key"),
));
}
Add article in session :
/**
* #Route("/shop/add/{id}", name="add_article")
*
*/
public function addArticlelAction(Request $request, $id)
{
$session = $request->getSession();
if (!$session->has('panier'))
$session->set('panier', array());
$panier = $session->get('panier');
if (array_key_exists($id, $panier)) {
if ($request->query->get('qte') != null)
$panier[$id] = $request->query->get('qte');
} else {
if ($request->query->get('qte') != null)
$panier[$id] = $request->query->get('qte');
else
$panier[$id] = 1;
}
$session->set('panier', $panier);
return $this->redirectToRoute('panier');
}
UPDATE:
If $id in addArticlelAction is the product id then:
foreach ($produits as $produit) {
$article = new Article();
$article->setTitle($produit->getStock()->getTitle());
$article->setContent($produit->getStock()->getContent());
//problem here
$article->setQuantity($session->get('panier')[$produit->getId()]);
//
$article->setPrice($produit->getPrice());
$commande->addArticle($article);
$em = $this->getDoctrine()->getManager();
$em->persist($commande);
$em->flush();
}
should work, because for the moment you have two products (product1 who has id 1 and product 4 who has id 4). When you call /shop/add/{id}, you are adding to $session->get('panier')[1] and $session->get('panier')[4] the quantities. So, when you're in foreach (to store in DB), you need to access index 1 and index 4 ($produit->getId())

Array Collection persistence on symfony2

i'm using a event listener on the submit of a form where, i need to catch a xml file, open it and extract his contents, put it on an entity and add that to a collection from other entity.
right now this is works:
$builder->addEventListener(FormEvents::SUBMIT, function(FormEvent $event){
$entity = $event->getData();
if($entity){
$parent = $event->getForm()->getParent()->getData();
$gpx = $entity['gpx'];
if($gpx){
$xmlGpx = simplexml_load_file($gpx);
foreach ($xmlGpx->wpt as $pt) {
$point = new MonitoringPoint();
$point->setPoint(new \CrEOF\Spatial\PHP\Types\Geometry\Point((string) $pt['lat'], (string) $pt['lon']));
$point->setAltitude((float) $pt->ele);
$point->setDate(($pt->time->count() ? new \DateTime((string)$pt->time) : null ));
$point->setAccuracy((float) $pt->hdop);
$parent->addMonitoringPoint($point);
}
$fileName = $gpx->getClientOriginalName();
$directory = __DIR__.'/../../../../web/uploads/';
$date = new \DateTime();
$newFileName = md5($gpx->getClientOriginalName().$date->getTimestamp());
$gpx->move($directory, $fileName);
$fs = new Filesystem();
$fs->rename($directory.$fileName, $directory.$newFileName.'.gpx');
$parent->setGpx($newFileName.'.gpx');
}
}
});
$parent is an instance of Monitoring, if i open $parent i will see that the $point vars has been added on the collection monitoringPoints of the variable, and the gpx too.
but then i go so see the entity right before been persisted, inside newAction
$entity = new Monitoring($params);
$form = $this->createForm(new MonitoringType(), $entity, array(
'action' => $this->generateUrl('my_route'),
'method' => 'POST',
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
dump($entity);die;
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
}
and the collection is empty! but the gpx attribute contains the right value.
does the collection gets reseted?
i had to pass the points in to an array within the session, still think that was not the best option, but worked
$array = [];
foreach ($xmlGpx->wpt as $pt) {
$point = new MonitoringPoint();
$point->setPoint(new \CrEOF\Spatial\PHP\Types\Geometry\Point((string) $pt['lat'], (string) $pt['lon']));
$point->setAltitude((float) $pt->ele);
$point->setDate(($pt->time->count() ? new \DateTime((string)$pt->time) : null ));
$point->setAccuracy((float) $pt->hdop);
$point->setMonitoring($parent);
array_push($array, $point);
}
$session = new Session();
$session->getFlashBag()->add('array', $array);
in the newAction:
$em = $this->getDoctrine()->getManager();
$session = new Session();
$array = $session->getFlashBag()->get('array');
foreach($array[0] as $point) {
$point->setMonitoring($entity);
$entity->addMonitoringPoint($point);
}
$em->persist($entity);
$em->flush();
dont know why the array got reseted when it comes to the controller, cause i had setted the points in the entity during the submit

Symfony2 update row from array

I want update row setting new values from array, now Iset one by one aribute:
$em = $this->getDoctrine()->getManager();
$company = $em->getRepository('CatalogWebBundle:ComCompany')
->findOneBy(
array('cmpCode' => $id)
);
$company->setCmpName($_POST['name']);
$company->setCmpCode($_POST['code']);
$em->flush();
Maybe exist solution to set all atributes from array, some like this ?
$company = $_POST;
Consider using Symfony Form and use like this:
<?php
$request = $this->getRequest(); // or inject Request to the action method like myAction(Request $request)
$em = $this->getDoctrine()->getManager();
$company = $em->getRepository('CatalogWebBundle:ComCompany')
->findOneBy(
array('cmpCode' => $id)
);
$form = $this->createForm('formName', $company);
$form->handleRequest($request);
if($form->isValid()) {
// if you want, you can get entity here,
// but passing an entity in 2nd param of createForm
// provides automatic binding data
$data = $form->getData();
$em->flush();
// do some action after submitting form...
return $this->redirect($this->generateUrl('companies'));
}
Read more about creating forms:
http://symfony.com/doc/current/book/forms.html
And about regitering forms as services for futher use named form in createForm('NAME_HERE', $bindObjectHere):
http://symfony.com/doc/current/book/forms.html#defining-your-forms-as-services

symfony doctrine update from form

I'm stuck since this morning with the update of an entity.
Don't know what I'm missing, pretty sure this is a newbie mistake.
I'm just trying to update something via a form.
The controller:
public function editAction($pid, $plid, Request $request)
{
$plan = new Plan();
$form = $this->createForm(new PlanType(), $plan);
$plan = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Plan')->findOneByPlid($plid);
$project = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Project')->findOneByPid($pid);
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
$em = $this->getDoctrine()->getManager();
$em->flush();
return $this->redirect($this->generateUrl('qarth_framework_plan_edit', array('pid' => $pid, 'plid' => $plid)));
}
return $this->render('QArthFrameworkBundle:Pages:plan_edit.html.twig', array(
'plan' => $plan,
'project' => $project,
'form' => $form->createView(),
));
}
The form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('description', 'textarea');
}
The Entity : http://pastebin.com/bTqKehyQ
With the profiler I can see that my post parameters are well posted
plan {"name":"fsggsfgsf","description":"gsfgsfgsf","_token":"7d089aca0203c60fe1e617488e532ac966101440"}
But I can't see any trace of an update query or something else.
If you have an idea, it will be great!
Many thanks,
Ben
Need to pass the queried plan to the form.
public function editAction($pid, $plid, Request $request)
{
$plan = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Plan')->findOneByPlid($plid);
$project = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Project')->findOneByPid($pid);
// Create a new one if not found
if (!$plan) $plan = new Plan();
// Build your form using queried or new plan
$form = $this->createForm(new PlanType(), $plan);
$form->handleRequest($request);
// Checks for POST as well as validity
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($plan); // To handle new plans, no impact for existting plans
$em->flush();
// Rest is the same

Resources