Symfony sfWidgetFormDoctrineChoice displays id numbers instead of actual values - php

I have a user table and an article table. When creating a new Article using Symfony's generated forms, the User dropdown/select shows numbers (user id numbers like 1, 2, 3...) instead of User Names.
I can obviously overwrite the form with a custom one in order to make sure this select element is populated with user names instead of their ID numbers, but I figured Symfony would have maybe already figured this one out and there was just something I was missing...
Should it show names by default or did I do something wrong?

Actually, it will call the model's __toString() method. You can override it in your models to return any string value.
class User extends BaseUser {
public function __toString() {
return $this->getUsername();
}
}
Alternatively, you can pass the 'method' option to the choice widget. For example:
new sfWidgetFormDoctrineChoice(array('Model' => 'User', 'method' => 'getUsername'))

I figured out the problem myself. Basically if you have a table column called name, then Symfony will automatically use this field to populate a dropdown menu. I happen to be using username. Pretty cool design idea, but I don't remember reading it in the Symfony docs. Oh well.

Related

Two fields mapping in symfony2

Is it possible to collect and map two fields from form to one property?
Details:
I have an array field in my entity:
#ORM\Column(name="custom", type="simple_array")
where admin can specify (multi choice) custom options for the product - for example:
$product->setCustom( array('customText', 'customNumber') );
So the user should have two fields in his order form - text and number. Then I want to save them:
$order->setCustomOptions(array(
'customText' => 'Foo',
'customNumber' => '100',
));
In order entity there is just array field type instead of simple_array.
User can't add new options so the collection field type isn't a good choice in my opinion.
I have also tried to use data transformer but I think it can be applied only to one field.
Tell me if it's not clear. I don't need a complete solution but a hint what to choose.
Finally, I created two additional fields in my Entity (like DonCallisto suggested) without mapping to Database and rendered them in the form. Then instead of using DataTransforem, I used a setter with #ORM\PrePersist and #ORM\PreUpdate to set custom values together.

Symfony 1.4 application "Edit" menu very slow

My Symfony 1.4 application "Edit" menu very slow. When I click on edit link it takes almost 2 minutes to response.
I am using the following function in my module's action.class.php file.
public function executeNew(sfWebRequest $request) {
$this->form = $this->configuration->getForm();
$this->employee_attendance = $this->form->getObject();
}
There is a common pitfall when using automatically generated forms in Symfony. When your form has a field which is a foreign key of a related model then a <select> element is created for this element. All the possible values of the related values are fetched from the database and populated as objects. Then the __toString() method is used on each object to display a user friendly value on the list. If the implementation of this function uses another related object then the relation is read from the database for each object separately.
For example, if you have in your form a field for related object Shift and the __toString method in the Shift class refers to another model, let's say:
function __toString()
{
return sprintf(
'%s - %s',
$this->getShiftType()->getName(),
$this->getName()
);
}
Then the ShiftType will be fetched from the database one by one for each Shift. If your select lists several thousands shifts you will have the same amount of database queries run each time you open the form (not to mention resources needed to hydrate objects).
There are two things that can be done to solve the problem:
usually the related object is set in some other way than being chosen by the user so you can just skip the widget altogether. Something like unset($this['shift_id']); in your form's setup function.
If you do need the select use a specific table method where you will limit the number of elements retrieved from the DB and/or join with any relevant tables (the ShiftType in our example). You can add an option to the widget in your form:
$this->widgetSchema['shift_id']->addOption(
'tableMethod',
'yourFunctionRetrievingJoinedTables'
);

Symfony Set Drop Down Value Based Upon ID

I am still getting my hands dirty with Symfony, so I am a bit ignorant on how to do something that should be pretty simple.
I have a form that I am creating in the controller and passing to the view:
$form = $this->createForm(new PurchaseOrderType($account), $purchaseOrder);
The form displays exactly how I need it to, no problems at all! I am trying to now make the form more dynamic so that it can auto select a drop down list based upon an "id" variable that I am passing into the form. The id equals 23 by the way.
So, I have a drop down of suppliers and one of the options value is 23. How do I automatically select this option? Sorry for my ignorance :)
Thanks!
Without the code of your form type, I can make only suggestion.
If I get it correctly, inside the purchase order entity, there is an other entity mapped, and that one is represented with an id.
The object, $purchaseOrder has to have the other entity, then in the form type, when you set up the drop down field, you have to specify - with the correct name it shouldn't be a problem - the foreign id.
But you need of course data for the drop down field what can be the result of a SELECT * query.

Proper CakePHP model to natively use multiple select and "dynamic" multiple select (e.g. tags)

In my schema Test HABTM Variable (originally I used hasMany but I found more documentation using HABTM even though it seemed overkill to me).
I want to use a multiple select in a CakePHP form and I don't want to have trouble saving, retrieving and pre-filling the data (ie. ugly array manipulations in beforeSave and beforeFind, extra queries for retrieving the selected options and other things that may cause me to lose my hair even earlier than I probably will anyway).
One usecase is a multiple select where the options are known beforehand,
the other one needs to allow for creating new and deleting old options (I'm using select2).
With the help of cake bake and some model HABTM documentation that was I missing when I read the FormHelper documentation I found out that
I have to name my multiple select form field like the model that belongs to it i.e. Variable.
It's implicit in the FormHelper documentation, but definitely could be highlighted more.
Also implicit: Because the find() operation gets the possible values for a field, I had to call the fields in my Variable model id and name (how else would it know from the Model name in the input call what to display). I can change find's options but that broke the convention at some other step I think.
Inconsistently if I want to supply a list of possible values in the controller, I have to set a variable that is lowercase, camelized and pluralized (not uppercase and singular like my Model and like I have to name the form field, not lowercase, underscore-separated and singular like my name field and my table).
I thought I didn't need to set the possible options in the controller (because I either know them or they're added on-the-fly by the user, I don't really want to populate the DB with them beforehand), but I tried to wrap my head around the convention. I could not get it to work unless I populated the DB with them beforehand and set them in the controller.
That seems fragile or at least more narrow compared to the treatment of single selects.
My continuing problems
With HABTM I can't create new options on-the-fly (it's okay for one usecase, but not for another, which is more like tagging).
With HABTM I don't want to have to populate the DB with options. And I don't really want to set the options in the controller, but in the view (because I anticipate this will cause problems with multiple "Tests" on one page, if it doesn't then it's okay).
With HABTM it doesn't work when I change the Form->input to Form->select (doesn't really matter, but adds to that feeling of my solution being fragile).
With hasMany I got as far as automatically selecting values I filled in in the DB, but it does not destroy or create associations (i.e. delete no longer selected options in the child table, even though it is declared as dependent). I think here it's due to the fact, that I don't properly pass the IDs of the child table, but how would be the Cake way to do that?
Sample code
/* Model Variable.php */
class Variable extends AppModel {
public $belongsTo = 'Test';
}
/* Model Test.php */
class Test extends AppModel {
public $belongsTo = 'Study';
public $hasAndBelongsToMany = array(
'Variable' => array(
'className' => 'variable',
'joinTable' => 'tests_to_variables',
'foreignKey' => 'test_id',
'associationForeignKey' => 'variable_id',
'with' => 'TestsToVariables',
),
);
}
/* in baked TestsController.php */
$variables = $this->Test->Variable->find('list');
$this->set(compact('variables'));
/* in edit.ctp, the baked view */
echo $this->Form->input('Variable');
Cake Form::input() has options for multi select, it also auto fills the values and selects previously saved data.
How does this not fit your needs, Have you even tried what is explained in the book?
http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#creating-form-elements

additionals properties of a model in cakephp?

I'm starting to use cakePhp and I would like to know:
When I do a query(like with $this->Product->find(...)), I receive an array, right?
Then:
-If I've some non-db fields with default values that I've to display for each product, how do I do?
I saw virtual fields, but I cannot manage to put a static var into it
You can use the solution Anh Pham provided another thing you could do, if it's just setting the values to display them, is add them to the array in your controller after you have the results:
$result['Model']['desired_field_name'] = $static_field;

Categories