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?
Related
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()
]);
}
How to implement adding related Role entities better way? It would be nice to keep it inside of a form if possible or maybe if I add a method to an User entity directly... Is there built-in mechanism for it or what patter shall I use?
public function add(Request $request)
{
$data = $request->request->all();
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->submit($data);
if (false === $form->isValid()) {
return $form;
}
$user = $form->getData();
// Adding a Roles
if (!empty($data['user_roles'])) {
foreach ($data['user_roles'] as $value) {
// Checking if a Role is present in DB
$role = $this->getDoctrine()
->getRepository(Role::class)
->findOneBy(['role_name' => $value]);
if ($role) {
$user->setUserRole($role);
}
}
}
$this->em->persist($user);
$this->em->flush();
return new JsonResponse(
[
'status' => 'ok',
'last_insert_id' => $user->getId(),
],
JsonResponse::HTTP_CREATED
);
}
I've always worked like that and I've never had a problem. In fact, I don't even use symfony's forms because they're not that flexible. The best way to do it is the one that you feel more comfortable with. Just be sure to be clean and consistent.
Of course you can add a method to the User entity, but it's just a matter of modularization, that's not very necessary in this case.
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;
}
How would you do a functional test (not unit tests) of a form binded to an entity ?
Context
Let's say you have an entity "Car", with a field "id" and another field "numberPlate", and a page to edit data about a car.
CarController.php :
//...
public function imsiDetailsChangeAction(Request $request)
{
$car_id = $request->get('car_id');
$car = $this->getDoctrine()->getRepository('ClnGsmBundle:Car')->Find($car_id);
if ($simCard != null)
{
$form = $this->createForm(new CarType()), $car);
if($request->isMethod('POST'))
{
$form->bind($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$em->flush();
return $this->redirect($this->generateUrl('car_view', array('car_id' => $car->getId())));
}
}
}
else
{
throw new NotFoundHttpException();
}
return $this->render('SiteBundle:Car:carEdit.html.twig', array('car' => $car, 'form' => $form->createView()));
}
//...
What I want
A test using phpUnit doing the following :
create a Car entity with the numberPlate "QWE-456"
load the page with the form
using the crawler, replace the numberPlate with "AZE-123" in the form, and submit the form
assert that my car entity's numberPlate now equals "AZE-123"
What I tried
(just in case: my own code is a bit different, here is what I would do with the car example)
CarControllerTest.php :
//...
public function SetUp()
{
//start kernel, stores entity manager in $this->em and client in $this->client
}
//...
public function testEditForm()
{
$car = new Car();
$car->setNumberPlate("QWE-456");
$this->entityManager->persist($simCard);
$this->em->flush();
$crawler = $this->client->request('GET', '/fr/Car/edit/'.$car->getId());
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$formNode = $crawler->filterXpath("//div[#id='main']//form");
$form = $formNode->form(array(
'car[plateNumber]'=>'AZE-123',
));
//var_dump($car->getPlateNumber());
$this->client->submit($form);
//var_dump($car->getPlateNumber());
$this->assertEquals('AZE-123',$car->getPlateNumber);
}
I expect this test to pass, and the second var_dump to print "AZE-123" instead of "QWE-456". But my entity isn't modified.
How should I do this ?
You should refresh the data reloading it from the database: the refresh method do it for you, so try this:
$this->client->submit($form);
$this->em->refresh($car);
$this->assertEquals('AZE-123',$car->getPlateNumber);
I suggest you to check before the HTTP Response in order to verify the correct interaction, as example:
$response = $this->client->getResponse();
$this->assertTrue($response->isRedirection());
Hope this help
I have a user table. In that table I have different fields. I only need to update the image column of the user table.
I have a form for uploading the image only. Even though the image is set but when I submit the form I get validations errors of other fields.
I know that the validation errors are because I passed the user object to the form and issued a isValid().
How do I only update the specific column like the image column?
public function updateImageAction(Request $request){
$form = $this->createForm(new UploadImageType(),new User(),[
'action' => $this->generateUrl('update_image')
]);
$form->handleRequest($request);
$user = $this->getUser();
if ($form->isSubmitted() && $form->isValid())
{
$em = $this->getDoctrine()->getManager();
$data = $form->getData();
dump($data);die;
$em->persist($data);
$em->flush();
}
return $this->render('photo.html.twig', [
'form' => $form->createView()
]);
}