symfony 4 - InvalidArgumentException: The current node list is empty - phpunit

Hi I'm trying to add symfony unit test for a form. This is my code...
$crawler = $this->client->request('GET', '/admin/user/new');
$form = $crawler->selectButton('Save')->form(array(
'user[displayName]' => 'user',
'user[username]' => 'user#yahoo.com',
'user[password]' => 'user123',
'user[phoneNumber]' => '1234789',
'user[roles]' => 'ROLE_USER',
));
$crawler = $this->client->submit($form);
$crawler = $this->client->followRedirect();
$this->assertGreaterThan(
0, $crawler->filter('html:contains("Le tue modifiche sono state salvate!")')->count()
);
But I only ends up with this error,
InvalidArgumentException: The current node list is empty.
It works when I try with language English but only fail when I change my default language to Italian in my app.

It appears to be I need italian translation for the button. The current node list is empty meant can't get $form = $crawler->selectButton('Save') node. since I have translated the interface to italy It had to be changed to italian wording.
$form = $crawler->selectButton('Salva')
And You can get by class or id so language will not matter.
$form = $crawler->filter('button.btn-success')
I'm keeping this in case anyone may lean something from it...

Related

How to create Field Collection Item by code in Drupal 8

How to create a Field Collection item for a node by program in Drupal 8. I have tried with below code, but it doesn't work. 'field_abc_inside' is the field of the Field Collection 'field_abc'.
$field_collection_item = entity_create('field_collection_item', array(
'field_name' => 'field_abc',
'field_abc_inside' => array('value'=> 'Test data'),
));
$field_collection_item->setHostEntity($node);
$field_collection_item->save();
$user_id = \Drupal::currentUser()->getAccount()->id();
$user = User::load($user_id);
$fc = FieldCollectionItem::create(array(
"field_name" => "field_hobbies",
));
$fc->set('field_hobby_name', 'Watch TV');
$fc->setHostEntity($user);
That code helped me but I have one observation.
\Drupal::currentUser() is the user object, which is clear since it is using it to retrieve the id().
Therefore no need to User::load() it again in line 2, redundant processing that will cause the function to take longer to run.
// Get the current user object
$user = \Drupal::currentUser();
// Prepare the new Field Collection Item object
$fc = FieldCollectionItem::create(array(
"field_name" => "field_hobbies",
));
// Sets more field values
$fc->set('field_hobby_name', 'Watch TV');
// Sets the host record; where the field collection will be attached into
$fc->setHostEntity($user);
// Saves it into an actual field collection record
$fc->save();

Symfony2: KnpPaginator only show the first page with POST form

I'm using this bundle in an application. The controller is the typical that shows a search form, take the response and process it (an example):
public function indexAction()
{
$request = $this->getRequest();
$example = new Example();
$form = $this->createForm(new ExampleFindType(), $example, array(
'action' => $this->generateUrl('example_find'),
'method' => 'POST',
));
$form->handleRequest($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$examples = $em->getRepository('ApplicationExampleBundle:Example')
->find_by_fields($example);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$examples,
$this->get('request')->query->get('p', 1),
20
);
return $this->render('ApplicationExampleBundle:Default:searchResults.html.twig',
array('pagination' => $pagination));
}
return $this->render('ApplicationExampleBundle:Default:index.html.twig',
array('form' => $form->createView(),
));
}
When I perform the search I see the results list and the paginator correctly. The problem appears when I press the link to the next page. The link id generated well, with the URL ending with "?p=2" but it seems that the form POST data is not resent because it sent me to the search form page ($form->isValid() is false).
If I change the form method from POST to GET and pass the parameters in the URL:
$form = $this->createForm(new ExampleFindType(), $example, array(
'action' => $this->generateUrl('example_find'),
'method' => 'GET',
));
the paginator works perfect.
Am I doing something wrong? Is possible to use a POST form?
I've searched an answer but all the KnpPagintor controller examples I've seen don't generate the query with forms, and this question hasn't helped me.
Thanks.
You shouldn't use POST method to get data.
Otherwise, if you need to use the POST method then you need the data in the session. However it's difficult to build a nice user experience while it just makes more sense to use a GET method.
You can find an extensive documentation about HTTP on MDN.
A GET method should be used when you request data.
A POST method should be used when you save data (like saving a comment into a database) or other data manipulation.
Google uses a GET on their own search page.
https://www.google.com/#q=symfony&start=10
q is what I searched for and start is the paginator value. They probably use an offset instead of a page number to avoid calculating the offset (faster and less expensive).

Setting a default entity value

I'm trying to set an entity form type to have a default value, i.e the user that is currently logged in.
My code is as follows:
EventType.php
->add('forUser', 'entity', array(
'label' => 'Staff',
'class' => 'BMUserBundle:User'
'property' => 'fullName',
'empty_value' => 'Select Staff'.
'query_builder' => function(EntityRepository $er) {
return $er->findAllStaff();
}
))
This works fine and returns all th staff members in the drop down.
I have also tried to do the following:
$form = $this->createForm(new EventType());
$form->get('forUser')->setData("USER_ENTITY") -> entity of logged in user
This doesn't seem to affect the form and it just lists the users with no default selected.
Am I approaching this correctly?
Thanks
When you instanciate your entity type in the controller, you first have to create a Event object with the user set for the "forUser" relation. Then you just have to pass as 2nd argument your Event object and it will automatically populate the type with.
Here is a small code example to show you how to do :
/src/Your/AppBundle/Controller/YourController.php
// get the authenticated user
$user = $this->get('security.context')->getToken()->getUser();
$event = new Event();
$event->setForUser($user);
$form = $this->createForm(new EventType(), $event);
But as forgottenbas said, you have to verify that your EventType has well the data_class option with your Event Classname as value. You'll get more information about it here.
If you let me tell you an off topic advice, you shouldn't use Event as ClassName because the event concept is well too present in Symfony2 development so it'll only obfuscate the code.
Good luck for your project, I hope it'll help you.

Change fields in node from code

How do I access the fields in a node in Drupal 7.
I have tried this but that do not work.
$node=node_load($nid);
$node->field_num[LANGUAGE_NONE][0]['value']=$num;
I think I have to be more specific:
I first create a node and set values on some fields like this:
$values = array(
'type' => 'scorings',
'uid' => $user->uid,
'status' => 1,
'comment' => 0,
'promote' => 0,
);
$entity = entity_create('node', $values);
$ewrapper = entity_metadata_wrapper('node', $entity);
$entity->field_rond_nid[LANGUAGE_NONE][0]['value']=$nid_scorekort;
$entity->field_golfid[LANGUAGE_NONE][0]['value']=$form_state['values']['golfid_1'];
$ewrapper->save(true);
entity_save('node', $entity);
$nid=$entity->nid;
This works fine. Then I want to access this node from another function (passing the nid to it) end set value to another field (field_score_1). I have tried this:
$node=node_load($nid, 'my_content type');
$node->field_score_1[LANGUAGE_NONE][]['value'] = $my_value;
But this do not work. Seams that node_load do not give me access to the fields.
Your node_load() call is incorrect.
From the Drupal API documentation for node_load() the function declaration is:
node.module node_load($nid = NULL, $vid = NULL, $reset = FALSE)
Your second parameter is a string, not a number, as $vid would be.
If node_load() returns a FALSE then it failed.
Perhaps you were wanting to use EntityFieldQuery() instead?

Symfony2 Forms - Cannot add/remove entities from a collection

I have a form for a "Person" entity that has a collection of "Nicknames".
I have implemented this following the guide in the cookbook (http://symfony.com/doc/current/cookbook/form/form_collections.html)
When I create a new "Person" I can add "Nicknames" as expected successfully.
Using a similar form I have an edit page. On the edit page I have set up the front end in the same way as the new page.
On the edit page, I can edit the existing nicknames and the other simple fields successfully. However, when I submit a new "Nickname" (or try to remove one), it does not work.
I have var_dump()'ed the request object before it is binded to the "Person" and I have var_dump()ed the "Person" object after binding. The request does have the "Nicknames" collection passed correctly. However, they are not being binded to the Person at all, despite the fact that everything is the same as the new page. Further, I can still edit the existing Nicknames so it is working on that front.
I cannot for the life of me figure out why Symfony isn't creating these new Nicknames or adding them to the Person as it should. I have looked around and searched but everything just confirms that it should be working - but it isn't.
Heres the entry for the Nicknames on the Person form type:
->add('nicknames', 'collection', array(
'type' => new NicknameType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'required' => false
))
Nickname type only has one field - "nickname" and its a text input.
Any help? Thanks for reading.
EDIT:
Here is the update action (changed Person to Player):
public function updateAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$player = $em->getRepository('SCDBAppBundle:Player')->find($id);
if (!$player) {
throw $this->createNotFoundException('Unable to find Player.');
}
$editForm = $this->createForm(new EditPlayerType(), $player);
$deleteForm = $this->createGenericIDForm($id);
$editForm->bindRequest($request);
if ($editForm->isValid()) {
$em->persist($player);
$em->flush();
return $this->redirect($this->generateUrl('admin_player_edit', array('id' => $id)));
}
return array(
'player' => $player,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
I realize that to actually persist removing nicknames I need to change the code to persist. I'm not even worried about persistence right now, because the main issue is that after I bind the request to the Player form, the $player object does not contain the updated Nicknames collection.
If you are not using Symfony master but 2.0.x, beware, because the "collection" type is buggy there. If you are using Symfony master however, make sure to include a recent version of Doctrine (2.2.3 or 2.1.7) because there two bugs have been fixed that affect the correct working of the "collection" type.
Maybe try to use NicknameType::class instead of new NicknameType().
And I suggest to add cascade: [ persist ] conf attribute to your entity.
You have to get the data from the request with:
$objPerson = $editForm->getData();
$em->persist($objPerson);
$em->flush();
Otherwise you update the old object without changes from the form.
Short: You have only updated the object which was loaded from the database before.

Resources