This questions is NOT about how to embed an entity that is simple and straightforward my question is about an abnormality I am seeing and can't reconcile.
I have an Entity (Contact) I have an "Email" relation on this and want to have the ability to embed Emails in my create new method.
So I do the usual embed steps:
1) Add my collection to my form (contactType.php)
->add('emails', 'collection', array(
'type' => new EmailType()
))
2) In the Controller I add a new empty Email entity and set that as my default data for my form
$entity = new Contact();
$email = new Email();
$entity->addEmail($email);
$form->createForm(new ContactType(), $entity);
This is where the issue occurs, going into "createForm" my $entity has a collection called Emails, coming out the $form is a blank ContactType, no Email attached to it... it's as if the defaultData is just being ignored.
If you have seen this or have any idea why this would happen I would love some input.
We have modified our getter to return an Associative Array and this seems to break the Form builder, The following breaks the Form Builder:
public function getContacts()
{
$array = new ArrayCollection();
$property = (is_array($this->contacts)) ? $this->contacts : $array;
foreach($property as $entity)
{
$array[$entity->getType()->getName()] = $entity;
}
return $array;
}
the basic getter is just
return $this->contacts;
Which works, it seems ArrayCollection() isn't a simple Associative Array as we assumed it could be.
Related
I am doing some tests with Symfony 4 Forms and the answer to my question might be very simple but I am really confused right now and I need fresh eye to understand the following strange behavior.
Here is the context : I have a page /edit which handle a form for an entity named Promoter in a very classic way but after passing the validation I am generating and setting a randon firstname then flush the entity (which is updated with the new data form the form and the new firstname), and after instead of redirecting to another page, I return to the same page with the new Promoter entity.
My expectation is the see the new generated firstname but in fact it shows the old one(the one send by the form to the controller) and I cannot understand why? Can somebody has a clue?
I should add that data in db are correctly updated.
The Controller code is:
/**
* #Route("/{id}/edit", name="promoter_edit", methods={"GET","POST"})
* #param Request $request
* #param Promoter $promoter
* #return Response
*/
public function editAction(Request $request, Promoter $promoter): Response
{
$form = $this->createForm(PromoterFormType::class, $promoter);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$firstname = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ'),0,5);
$promoter->setFirstname( $firstname );
$this->getDoctrine()->getManager()->persist($promoter);
$this->getDoctrine()->getManager()->flush();
}
return $this->render('promoter/edit.html.twig', [
'promoter' => $promoter,
'form' => $form->createView(),
]);
}
Thanks
It seems to me that when you post your form, you create the new one before updating your 'promoter'. You should try to reload your page after submitting your form.
if ($form->isSubmitted() && $form->isValid()) {
$firstname = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ'),0,5);
$promoter->setFirstname( $firstname );
$this->getDoctrine()->getManager()->persist($promoter);
$this->getDoctrine()->getManager()->flush();
return $this->redirect($request->getUri());
}
Does your PromoterFormType class have a field for firstname? Because otherwise it could override your newly set Firstname.
If so fix:
In PromoterFormType
->add('firstname')
needs the option: 'mapped' => false.
Or simple delete it from the formType.
More info
If not can you show us the FormType and the Promoter Entity?
Hope this helps for you!
I want to create a view where an event is displayed only if it is owned by the currently logged in user.
So I want to compare LoginID from the Events entity to the current user ID.
I tried with the following function:
public function showAction(Events $event, $id)
{
$em = $this->getDoctrine()->getManager();
$user=$this->getUser()->getLoginid();
$guests = $em->getRepository('VendorMyBundle:Guests')->findByEventid($id);
$events = $em->getRepository('VendorMyBundle:Events')->findByEventid($id);
// condition to display only events owned by the current user
if ($events->getLoginid()==$user){
$session = new Session();
$session->set('eventid', $id);
$deleteForm = $this->createDeleteForm($event);
return $this->render('events/show.html.twig', array(
'event' => $event,
'delete_form' => $deleteForm->createView(),
'guests' => $guests,
));
}
$this->addFlash('error', 'The event does not exist or you do not have permission to view it.');
return $this->redirectToRoute('home_page');
}
LoginID in Events entity is a Many-to-One relation property towards the Logins entity which is my user provider entity.
When I try to view with that method in my controller I get this: Error: Call to a member function getLoginid() on a non-object on the line with the IF statement.
Additional question would be, how do I compare 2 property values from 2 different entities?
Since the problem is that you are returning an array you have two choices, update the findByEventid() to return a single result
return $query->getSingleResult();
or
if ($events[0]->getLoginid()==$user){
..
}
Hope this help you.
The problem I am having now is related to entities and forms in Symfony2.
While creating the form that refers to one entity I can simply wire it by saying:
$user = new User();
$form->createForm(new UserType(), $user);
...
$manager->persist($user);
$manager->flush();
And that is working fine. But the problem raises when I have more complex form that is built based on other forms, e.g.
So, let's imagine I have a form called RegistrationType that contains two other forms called UserType wired to User entity and ProfileType wired to Profile entity.
Now, how can I handle that in the controller? I mean, I cannot do something like:
$user = new User();
$profile = new Profile();
$form->createForm(new RegisterType(), $user, $profile);
OR
$form->createForm(new RegisterType(), [$user, $profile]);
...
$manager->persist($user);
$manager->flush();
$profile->setUserId($user->getId());
$manager->persist($profile);
$manager->flush();
If I pass only $user, like so
$form->createForm(new RegisterType(), $user);
Symfony will complain that there are properties that are not mapped, of course I can set them to 'mapped' => false but then I have to set them later on manually.
What's the best way to handle this?
Thanks in advance!
Create UserType, ProfileType and RegistrationType forms. RegistrationType should add UserType and ProfileType as its children. Create Registration DTO and set it as data_class for RegistrationType. Then you can write something like
$user = new User();
$profile = new Profile();
$form->createForm(new RegistrationType(),
new Registration($user, $profile));
For my application in Zend Framework 2 I created a 'search form' in my layout.phtml.
I did this in my Application module by adding the search form as an variable.
(Form location Application/src/Application/Form/SearchForm.php)
Application/Module.php:
public function setFormToView($e)
{
$searchForm = new SearchForm();
$viewModel = $e->getViewModel();
$viewModel->setVariables(array(
'searchForm' => $searchForm,
));
}
The form directs to an Action in another module, here I want to handle what to do with
the incoming query.
MyModule/src/MyModule/Controller/MyModuleController.php
public function dataAction()
{
$form = new SearchForm();
$form->get('submit')->setValue('Add');
$website = $this->params()->fromQuery('search');
return array('searchForm', $form);
}
Getting the query 'search' is no problem, it works well. No I want to use my inputFilter I created under 'Application/src/Application/Model/Search.php'.
I tried to add this in my 'dataAction()' but no results, but I even can't change the submit value as I tried in my example above.
How do I set this in the right way in this situation? Or else, what is the right situation to handle a search form in layout.phtml.
Thanks in advance,
Nick
I have separate db_table classes for books, book_sections and users (system end users). in book table has columns for book_title, section_id(book_section) , data_entered_user_id(who entered book info).
go to this url to see the image(I'm not allow to post images bacause I'm new to stackoverflow)
img685.imageshack.us/img685/9978/70932283.png
in the backend of the system I added a form to edit existing book (get book id from GET param and fill the relevant data to the form). form has elements for book_title, book_section and data_entered_user.
to get exciting book data to "edit book form" I join book_section and user tables with book table to get book_section_name and username(of data_entered_user: read only- display on side bar)
go to this url to see the image(I'm not allow to post images bacause I'm new to stackoverflow)
img155.imageshack.us/img155/2947/66239915.jpg
In class App_Model_Book extends Zend_Db_Table_Abstract
public function getBookData($id){
$select = $this->select();
$select->setIntegrityCheck(false);
$select->from('book', array('id','section_id','data_entered_user_id',...));
$select->joinInner('section','book.section_id = section.id',array('section_name' =>'section.name' ));
$select->joinInner(array('date_entered_user' => 'user'),'book.date_entered_user_id = date_entered_user.id',array('date_entered_user_name' =>'date_entered_user.user_name' ));
$select->where("book.id = ?",$id);
return $this->fetchRow($select);
}
public function updateBookData($id,$title,$section_id,...)
{
$existingRow = $this->fetchRow($this->select()->where('id=?',$id));
$existingRow->title = $title;
$existingRow->section_id = $section_id;
//....
$existingRow->save();
}
In Admin_BookController -> editAction()
$editForm = new Admin_Form_EditBook();
$id = $this->_getParam('id', false);
$bookTable = new App_Model_Book();
$book_data = $bookTable ->getBookData($id);
//set values on form to print on form when edit book
$editForm->book_title->setValue($book_data->title);
$editForm->book_section->setValue($book_data->section_name);
//........
//If form data valid
if($this->getRequest()->isPost() && $editForm->isValid($_POST)){
$bookTable = new App_Model_Book();
$bookTable ->updateBookData(
$id,
//get data from submitted form
$editForm->getValue('title'),
//....
);
when editing an exsiting book
get data from getBookData() method on App_Model_Book class
If form data is valid after submiting edited data, save data with updateBookData() method on App_Model_Book class
but I saw that if I created a custom
Db_Table_Row(extends Zend_Db_Table_Row)
class for book table with
book_section_name and
data_entered_user_name I can use it
for get existing book data and save it
after editing book data without
creating new Book(db_table) class and without calling updateBookData() to save updated data.But I don't know which code I should write on custom
Db_Table_Row(extends Zend_Db_Table_Row)
class.
I think you can understand my problem, in simple
how to write a custom db_table_row class to create a custom row with data
form 2 joined tables for a perticular db_table class ?
I'm new to zend framewok and to stackoverflow. forgive me if you confused with my first question.
Thanks again.
1) at your db_table class create field which contain row class, for example:
protected $_rowClass = 'App_Model_Db_Books_Row';
and add reference map for parent tables:
protected $_referenceMap = array(
'Section' => array(
'columns' => 'sectionId',
'refTableClass' => 'App_Model_Db_Sections',
'refColumns' => 'id'
),
'User' => array(
'columns' => 'userId',
'refTableClass' => 'App_Model_Db_Users',
'refColumns' => 'id'
)
);
2) at row class you must define variables for parent tables:
protected $section;
protected $user;
In such cases i create method called "load":
public function load()
{
$this->section = $this->findParentRow('App_Model_Db_Sections');
$this->user = $this->findParentRow('App_Model_Db_Users');
}
And in constructor i call this method:
public function __construct(array $config = array())
{
parent::__construct($config);
$this->load();
}
As a result after:
$book_data = $bookTable ->getBookData($id);
you can access data from reference table, for example:
$book_data->section->name = "Book Section";
$book_data->section->save();