Symfony -> overwriting existing entity on update - php

Im creating a simple user class
- User -> entity
- Address -> entity
When a user got created i create a address record in my db.
Now when a user gets edited and changed his addres :
If the address exist he need to take that existing address
if the address not exist Symfony needs to create a new one and use the new address.
Atm I can create users and their address, but when I edit a users address:
The current existing adress get overwrited instead of creating a new one.
Maybe i missed some logic or am i doing it wrong.
here's my code :
public function editAction(Request $request,Users $user)
{
$form = $this->createForm(UserForm::class, $user);
if ($request->getMethod() == 'POST') {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$form = $form->getData();
$this->tryEditAction($user, $form);
return $this->redirectToRoute('admin_userslist');
}
}
$label = "Gebruiker aanpassen";
return $this->render('#ProjectUser/backend/edit.html.twig', array(
'form' => $form->createView(),
'user' => $user,
'label' => $label,
));
}
And here is the TryEditAction :
public function tryEditAction($user, $form)
{
$formAddress = $form->getAddress();
$formAddressStreet = $formAddress->getStreet();
$formAddressStreetNr = $formAddress->getStreetNr();
$formAddressStreetBus = $formAddress->getStreetBus();
$entityManager = $this->getDoctrine()->getManager();
//***
// Getting the entitymanager to get all addresses stored in our db
// Check if this address exist, so we change or edit the address accordingly to the user
//**
$address = $entityManager->getRepository('ProjectLocationBundle:Address')
->findOneBy(
array(
'street' => $formAddressStreet,
'street_nr' => $formAddressStreetNr,
'street_bus' => $formAddressStreetBus
)
);
if($address):
$foundAddress = $address;
$user->setAddress($foundAddress);
$foundAddress->setUser($user);
$entityManager->persist($foundAddress);
else:
$newAddress = new Address();
$newAddress = $formAddress;
$entityManager->persist($newAddress);
$entityManager->flush($newAddress);
$user->setAddress($newAddress);
endif;
// dump($user); die;
$userName = $user->getUsername();
$slug = $this->slugify($userName);
$user->setSlug($slug);
$entityManager->persist($user);
$entityManager->flush();
return $user;
}

Related

Symfony get users on relation to many to many

in a many to many relationship
In the controller , how can I get all the users join to a specific event?
I have tried to get users from the specific event, but it get all users of all events.
I need to get users from the specific event because i want notify all those users via email.
capture of table sql
public function notificarATodos(MailerInterface $mailer, Request $request, UserPasswordEncoderInterface $passwordEncoder, Evento $evento, User $user): Response
{
$user_repo = $this->getDoctrine()->getRepository(User::class);
$user = $user_repo->findAll();
$evento = $this->getDoctrine()->getRepository(Evento::class)->findOneById($evento);
//$user->GetEventos($evento);
$evento->GetUsers($user);
dump($user);die;
$form = $this->createForm(ContactoFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $user->getEmail();
$contactFormData = $form->getData();
$email = (new Email())
->from('')
->to($user->getEmail())
->subject($contactFormData['asunto'],
'text/plain')
->text($contactFormData['mensaje'],
'text/plain');
$mailer->send($email);
$this->addFlash('success', 'EMAIL ENVIADO CORRECTAMENTE');
return $this->redirect($this->generateUrl('evento_detalle', ['id' => $evento->getId()]));
}
return $this->render('user/contactar.html.twig', [
'form' => $form->createView(),
]);
}
This is pretty much exactly the same as https://stackoverflow.com/a/65905944/6127393
$users = $evento->GetUsers();
...
if ($form->isSubmitted() && $form->isValid()) {
foreach($users as $user){
$email = $user->getEmail();
...
}
}

How to explain this issue and what should be the best solution about Symfony serializer/csv decoder

I am trying to make a simple CSV uploader with contacts and make them as array using Symfony serializer/CSV encoder. The problem is that when i get data from csv and i dump it i get everything fine i think. But when i want to loop over the array to echo email field or try to create new Objects and save them to database i get an error that index 'Email Address' is undefined. How that can be possible, if when i var_dump in a loop and die after first array on the list i see that 'Email Address' field exists.
Link to image - https://imgur.com/a/7bSJT0z
/**
* #Route("/upload-csv", name="upload")
*/
public function uploadCsv(Request $request)
{
$form = $this->createForm(ContactType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$em = $this->getDoctrine()->getManager();
$data = $form->getData();
$file = $data->getCsv();
//dump($file);
$serializer = $this->container->get('serializer');
$cons = $serializer->decode(file_get_contents($file), 'csv');
foreach ($cons as $con)
{
$contact = new Contact();
$contact->setEmail($con['Email Address']);
$contact->setFirstName($con['First Name']);
$contact->setLastName($con['Last Name']);
$contact->setCountry($data->getCountry());
$em->persist($contact);
}
$em->flush();
}
return $this->render('base.html.twig', [
'form' => $form->createView()
]);
}

Populating form data from entity in Symfony2

I have an action that basically renders a form and I want it to be a new form if the ID is null and an edit form if the ID matches with the PK in the DB. Obviously my logic is wrong because a new form is rendering every single time. .
public function editGlobalFirewallFilter(Request $request, Entities\GlobalFirewallFilter $firewall_rule = null) {
n
// Check if we have a valid rule. If not create a new blank one and associate our account id
// if( ! $firewall_rule ) {
// $results = $this->getDoctrine()->getRepository('bundle:GlobalFirewallFilter');
// $rules = $results->findAll();
// $firewall_rule = new Entities\GlobalFirewallFilter();
// }
$firewall_rule = new Entities\GlobalFirewallFilter();
// Generate our form
$form = $this->createForm(new SAForms\GlobalFirewallRuleType(), $firewall_rule);
$form->handleRequest($request);
if($form->isValid()) {
// Save our firewall rule
$em = $this->getDoctrine()->getManager();
$em->persist($firewall_rule);
$em->flush();
return $this->redirect($this->generateUrl('_dashboard__global_firewall'));
}
return array(
'title' => $firewall_rule->getFirewallFilterId() ? 'Edit Rule' : 'New Rule',
'form' => $form->createView(),
);
}
You should use the form generator command to be oriented in the right way :
Generating a CRUD Controller Based on a Doctrine Entity
http://symfony.com/doc/current/bundles/SensioGeneratorBundle/commands/generate_doctrine_crud.html
use this command :
php app/console generate:doctrine:crud
I will generate the skeleton of you controller with all the standard actions as wanted, in your specifica case, updateAction, newAction, and editAction.
I am not quite sure why are there results and rules - you don't use them. I think this code should do the trick.
public function editGlobalFirewallFilter(Request $request, Entities\GlobalFirewallFilter $firewall_rule = null) {
// Check if we have a valid rule. If not create a new blank one and associate our account id
$firewall_rule = $firewall_rule ?: new Entities\GlobalFirewallFilter();
// Generate our form
$form = $this->createForm(new SAForms\GlobalFirewallRuleType(), $firewall_rule);
$form->handleRequest($request);
if($form->isValid()) {
// Save our firewall rule
$em = $this->getDoctrine()->getManager();
$em->persist($firewall_rule);
$em->flush();
return $this->redirect($this->generateUrl('_dashboard__global_firewall'));
}
return array(
'title' => $firewall_rule->getFirewallFilterId() ? 'Edit Rule' : 'New Rule',
'form' => $form->createView(),
);
}
P.S. Sadly I can't comment yet.. Can you provide controller actions where you use this function?

Symfony 2 - Entity has to be managed or scheduled for removal for single computation

When I am submitting symfony2 form I got the following error:
Entity has to be managed or scheduled for removal for single computation
What does this error mean?
I am using the form which is aimed at adding new item to DB. I have multiple ManyToOne relations in the form.
/**
* This code is aimed at checking if the book is choseen and therefore whether any further works may be carried out
*/
$session = new Session();
if(!$session->get("App_Books_Chosen_Lp")) return new RedirectResponse($this->generateUrl('app_listbooks'));
$request = $this->get('request');
$em = $this->getDoctrine()->getManager();
if($item_id != null)
{
/* THIS CODE IS NOT EXECUTED IN THE GIVEN CASE */
}
else
{
// Add
$item = new Items();
$form = $this->createForm(new ItemsType(), $item);
$form->add('save', 'submit', array('label' => 'Add item'));
}
$form->remove('documentid');
$form->remove('book');
$form->handleRequest($request);
if ($form->isValid()) {
if($item_id != null)
{
/* THIS CODE IS NOT EXECUTED IN THE GIVEN CASE */
}
else
{
/* HERE ERROR OCCURS */
// Add
$book = $em->getReference('AppBundle:Books', $session->get("App_Books_Chosen_Lp"));
if( $book ) $item->setBook($book);
$doc = $em->getReference('AppBundle:Documents', $doc_id);
if( $doc ) $item->setDocumentid($doc);
$em->flush($item);
$session = new session();
$session->getFlashBag()->add('msg', 'Item was added.');
$url = $this->generateUrl("app_documents_details", array("id" => $doc_id));
return $this->redirect($url);
}
You need to persist your entity to let the EntityManager knows that it exists.
$em->persist($item);
$em->flush($item);

How to create a step by step form with Phalcon in PHP

I'm currently working on a project using the Phalcon Framework that has pages with complex forms and a lot of inputs, to break it down nicely I'm dividing the forms into a step-by-step process.
How would one validate the form on each step before going to the next step and then save the whole form on the final step?
I can't seem to find anything documented about this sort of process as it likes to validate the form in it's entirety if I use the form builder.
Simple, just create a custom methods in your form class to validate any step, and the posted data from some step save into message class and store it into session by "stepX", when posted data is not valid just set defaults from post. When valid save it into session as i describe above.
For example how i mean "controller"
<?php
class MyController extends BaseController {
public function processStep1Action(){
$form = new MyForm();
if($this->request->isPost()){//im using my custom request class
if(!$form->isValid($this->request->getPost()){
//error messages goes here
$form->setDefaultsFromRequest($this->request); // it will set the filled data
}
else {
$messageClass = new MyMessageContainer();
$messageClass->setData($this->request);//inside parse requested data into message class, or parse it as $messageClass->name = $this->request->getPost('name');
$this->session->save('step1',$messageClass); //maybe it would be want to serialize it
//then redirect to the step 2 or x
}
}
}
}
So in the next step you can access data from sessions $this->session->get('step1'); so you can in final step load all posted data and store it into DB.
I hope this helps! :)
here is my form maybe it can be helpful for you.
<?php
namespace Manager\Library\Forms\User;
use Phalcon\Forms\Form,
Phalcon\Forms\Element\Email,
Phalcon\Forms\Element\Select,
Phalcon\Forms\Element\Password,
Phalcon\Forms\Element\Check,
Phalcon\Validation\Validator\Confirmation,
Phalcon\Validation\Validator\StringLength,
Phalcon\Forms\Element\Submit,
Phalcon\Validation\Validator\PresenceOf,
Model\Group;
class AddUser extends Form {
public function initialize()
{
$email = new Email('email');
$email->addValidators(array(
new \Phalcon\Validation\Validator\Email(array(
'message' => 'Nezadali jste email nebo má nesprávny tvar(email#domena.tld).'
))
));
$this->add($email);
$this->initGroupElement();
$password = new Password('password');
$password
->addValidator(new StringLength(array('min' => 6,'messageMinimum' => 'Nezadali jste heslo nebo je příliš krátke, minimální počet znaků je 6.')))
->addValidator(new Confirmation(array('with' => 'password-again',"message" => "Zadané hesla se neshodují.")));
$this->add($password);
$repeatPassword = new Password('password-again');
$this->add($repeatPassword);
$this->initializeProfileElements();
$active = new Check('active',array('value' => 1));
$this->add($active);
$this->add( new Submit('save') );
\Phalcon\Tag::setDefault('password', '');
\Phalcon\Tag::setDefault('password-again', '');
}
public function initializeEdit(){
$email = new Email('email');
$email->addValidators(array(
new \Phalcon\Validation\Validator\Email(array(
'message' => 'Nezadali jste email nebo má nesprávny tvar(email#domena.tld).'
))
));
$this->add($email);
$this->initGroupElement();
$password = new Password('password');
$this->add($password);
$repeatPassword = new Password('password-again');
$this->add($repeatPassword);
$this->initializeProfileElements();
$active = new Check('active',array('value' => 1));
$this->add($active);
$this->add( new Submit('save') );
\Phalcon\Tag::setDefault('password', '');
\Phalcon\Tag::setDefault('password-again', '');
}
protected function initGroupElement(){
$auth = \Core\Auth::getIdentity();
$groups = new Group();
// $groups->addColumns(array('id','name'));
//set global condition about Super Admin
$groups->addFilter('id', 1,'<>');
if($auth){
//set restrictions for main groups
if((int)$auth->group_id === 1){ //super admingroup
//no filter
}
else if((int)$auth->group_id === 2){ //admin group
$groups->addFilter('id', 1,'>');
}
else if((int)$auth->group_id === 6){//Provozovatel group
$groups->addFilter('id',array(3,6,7));
$groups->addFilter('public', 1,'=',true);
}
else { // other groups
$groups->addFilter('public', 1);
}
}
$groups = $groups->findFiltered();
$groupElement = new Select('group');
foreach($groups as $group){
$groupElement->addOption(array($group->id => $group->name));
}
$this->add($groupElement);
}
protected function initializeProfileElements(){
$forename = new \Phalcon\Forms\Element\Text('forename');
$this->add($forename);
$surname = new \Phalcon\Forms\Element\Text('surname');
$this->add($surname);
$street = new \Phalcon\Forms\Element\Text('street');
$this->add($street);
$postal = new \Phalcon\Forms\Element\Text('postal');
$this->add($postal);
$city = new \Phalcon\Forms\Element\Text('city');
$this->add($city);
$ic = new \Phalcon\Forms\Element\Text('ic');
$this->add($ic);
$dic = new \Phalcon\Forms\Element\Text('dic');
$this->add($dic);
}
public function setDefault($fieldName,$value){
\Phalcon\Tag::setDefault($fieldName, $value);
}
public function setDefaults($object){
if($object instanceof \Model\User){
$this->setDefaultsFromObject($object);
}
else if($object instanceof \Phalcon\Http\Request){
$this->setDefaultsFromRequest($object);
}
}
protected function setDefaultsFromObject(\Model\User $user){
$profile = $user->getRelated('\Model\Profile');
\Phalcon\Tag::setDefaults(array(
'email' => $user->email,
'group' => $user->group_id,
'active' => $user->active,
'forename' => $profile->forename,
'surname' => $profile->surname,
'street' => $profile->street,
'city' => $profile->city,
'postal' => $profile->postal,
'ic' => $profile->IC,
'dic' => $profile->DIC
));
}
protected function setDefaultsFromRequest(\Phalcon\Http\Request $request){
\Phalcon\Tag::setDefaults(array(
'email' => $request->getPost('email'),
'group' => $request->getPost('group'),
'active' => $request->getPost('active')
));
\Phalcon\Tag::setDefaults(array(
'forename' => $request->getPost('forename'),
'surname' => $request->getPost('surname'),
'street' => $request->getPost('street'),
'city' => $request->getPost('city'),
'postal' => $request->getPost('postal'),
'ic' => $request->getPost('ic'),
'dic' => $request->getPost('dic')
));
}
}
In addition to Kamil's answer, another option to consider is to use Javascript on the front-end to handle your multi-step form. This will add some complexity as you will need to have the javascript to handle the form steps and do preliminary validation, but it only requires a single submit where you can validate content within a single method.

Categories