Laravel Multiple Form Request Validation - php

I have products and software and movie belongs to product. I have created two validation requests and want to validate them like shown below.
public function store(StoreProductRequest $old_request)
{
if ($old_request->type == 'MOVIE')
$request = new StoreMovieRequest;
else
$request = new StoreSoftwareRequest;
$request = $old_request;
$request->validate();
}
Is there any way to achieve this in Laravel 5.1? I hope you understand my question.

One way of doing what you want to achieve is
public function store(StoreProductRequest $old_request){
if ($old_request->type == 'MOVIE'){
$request = new Requests\StoreMovieRequest;
$this->validate($old_request, $request->rules());
//validation passed for StoreMovieRequest
}
else {
$request = new Requests\StoreSoftwareRequest;
$this->validate($old_request, $request->rules());
//validation passed for StoreSoftwareRequest
}
}

Related

Symfony / phpUnit : functional test of a form modifying an entity

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

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);

Update form Cakephp 3

I am currently working on a project using cakephp 3.
I have a form to add clients which works using this in my controller :
public function add(){
$clients = $this->Clients->newEntity();
if($this->request->is('post')){
$clients = $this->Clients->patchEntity($clients, $this->request->data);
if($this->Clients->save($clients)){
$this->Flash->success(__('Client has been created.'));
return $this->redirect(['controller'=>'Clients','action'=>'index']);
}
$this->Flash->error(__('Client hasnt been created.'));
}
$this->set('clients',$clients);
}
Then I want to have the possibility to modify one of my client.
I have a table of clients and when I click on of them, I have a modify button coming (jQuery).
Then I'm on my modify page. I did some test with the doc from cake but it seems I don't understand how it works and what tools should I use.
For the moment, I have this on my Controller:
public function modify($id = null){
if(empty($id)){
throw new NotFoundException;
}
$clients = $this->Clients->get($id);
/* there should be the modify code */
$this->set('clients', $clients);
}
I don't really know what to use as I said... Any help pls?
The code for editing a record is quite straight forward:
public function modify($id = null){
if(empty($id)){
throw new NotFoundException;
}
$client = $this->Clients->get($id);
if ($this->request->is(['post', 'put']) {
$client = $this->Clients->patchEntity($client, $this->request->data);
if ($this->Clients->save($client)) {
return $this->redirect($someURL);
}
}
$this->set('client', $client);
}

Symfony2: How to go back to a page where the request of a form was send from

I have a link: mysite/productnumber_2.html. On this Site I have a formular in a twig template, the action of this form leads to .../createAssessment.
In my controller I do things like save in a DB.
My question is, how can I go back to the url mysite/productnumber_2.html?
My function in teh controller looks like this:
/**
*
* #Route(path = "/createassessment", name="create_assessment", methods = "POST")
* #param Request $request The Request object
* #return RedirectResponse
*/
public function createAssessmentAction(Request $request) {
$form = $this->createForm(new AssessmentType());
$form->handleRequest($request);
if ($form->isValid()) {
$assessment = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($assessment);
$em->flush();
return $this->redirect( ## WHAT DO I HAVE TO PUT HERE?? ## );
}
}
You could redirect for request referer:
return $this->redirect($request->headers->get('referer'));
Or even better for defined route:
return $this->redirect($this->generateUrl('your_route'));
where your_route is path to you mysite/productnumber_2.html page.

CakePHP Security - Prevent Form Injection

I currently have 1 table, Users which looks like this
|**id**|**username**|**password**|**role**|**email**|
I'm using CakePHP's form helper to automatically fill in editable form fields. I'm creating an edit page in which users can change there username/password/email, but should NOT be able to change their role. I'm currently checking to make sure the user hasn't injected a role POST field into the request and was wondering if there is any better way to do this? It's trivial in this scenario with such a small table, but I can see this becoming tiresome on fields/tables with a large amount of columns. My current edit action looks like this.
public function edit($id = null)
{
$this->User->id = $id;
if(!$this->User->exists())
{
throw new NotFoundException('Invalid user');
}
$userToEdit = $this->User->findById($id);
if(!$userToEdit)
{
throw new NotFoundException('Invalid user');
}
if($this->getUserRole() != 'admin' && $userToEdit['User']['owner'] != $this->Auth->user('id'))
{
throw new ForbiddenException("You do not have permission to edit this user");
}
if($this->request->is('post') || $this->request->is('put'))
{
//Do not reset password if empty
if(empty($this->request->data['User']['password']))
unset($this->request->data['User']['password']);
if(isset($this->request->data['User']['role']))
unset($this->request->data['User']['role']);
if($this->User->save($this->request->data))
{
$this->set('success', true);
}
else
$this->set('success', false);
}
else
{
$this->request->data = $this->User->read();
//Prevent formhelper from displaying hashed password.
unset($this->request->data['User']['password']);
}
}
The third parameter of save() method lets you to define the list of fields to save. Model::save() docs
$this->User->id = $this->Auth->user('id');
$this->User->save($this->request->data, true, array('username', 'email'))

Categories