Using doctrine translatable together with Symfony 2 forms - doctrine-orm

I have Entity in my app, which has 2 translatable fields, using Doctrine Translatable Extension:
class Page implements Translatable
{
/......
/**
* #var string $name
* #Gedmo\Translatable
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var text $content
* #Gedmo\Translatable
* #ORM\Column(name="content", type="text")
*/
private $content;
/........
}
I use one table for multiple entities translations.
Now i would like to use one form to get the original and translated (to 1 language) values for these attributes, so it should have 4 fields.
I've defined new form derivating from AbstractType and tried to add those 2 fields using FormBuilder, but it says that their corresponding entities do not contain these fields. I've tried to add these fields to entities, and declare getters for them, but the only way i know to get translations for entities is to use dedicated entity manager and AFAIK providing entity manager access to entity isn't good practice.
Is there a way to use forms to handle such thing?

I know it's an old question, but anyway.
You could put the fields for translated content using FormBuilder with attribute:
array('mapped'=>false)
Take the data like this:
$form->get('field_name')->getData();
and then persist it like this
https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/translatable.md#multi-translations
I hope it helps somebody.

Related

how to consider annotation groups in a ObjectConstructor

JMSSerializer comes with a Doctrine Object Constructor that does its job, but imagine an Entity with two properties forming a primary key:
UserBase
prop annotated with #ORM\Id and #Serializer\Groups({"1"})
- username
prop annotated with #ORM\Id and #Serializer\Groups({"2"})
- email
User extends UserBase
- other props here, no Id defined.
one property key is excluded by using group=1 while deserializing. The client potentially still sends both email and username. email should not be considered though.
Unfortunately, if you pass the two properties in the body, DoctrineObjectConstructor does not check if something is excluded by deserialization, so it tries to load the Entity from the DB, according to the two values:
foreach ($classMetadata->getIdentifierFieldNames() as $name) {
if ( ! array_key_exists($name, $data)) {
return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
}
$identifierList[$name] = $data[$name];
}
What I would like to do is taking into account my annotated groups, so as to use the fallbackConstructor in case some property forming the identifier is missing.
As a starter this is a good point: I created my own service, by passing along the annotationDriver. Then, if the property forming the identifier is not associated with the actual group:
$classMetadata = $this->annotationDriver->loadMetadataForClass($metadata->reflection);
$classMetadata->properties //here groups are listed for each property
I can fall back to the fallbackConstructor, as if I had not passed that property in the body
...not so fast! My Entity User extends a UserBase where all my identifier are, so I should take into account hierarchy, possibly in a generic way.
Any hint?
Alright, JMSSerializer's Object Constructor does not consider serialization groups when determing identifiers. Hence, if you include all the IDs in your object, whether they are part of the actual context group or not, they will be counted in.
I created an alternative version of the Object in order to fix this misbehavior (at least for me). Hope it helps

Update doctrine entity with ArrayCollection field

I have problem with update entity with relations (one to many, many to one). I trying to add some new element to ArrayCollection when update, but nothing to do.
Here is my code of create and add relation:
$auctionPhoto = new AuctionPhoto();
$auctionPhoto->setAuction($auction);
$auctionPhoto->setPath($path);
$auction->getPhotos()->add($auctionPhoto);
All is running by doctrine entity listener (preUptade). The same code is do when I create entity (prePersist), but then is works fine.
I debug this and before persist I have in Auction object right relations, but nothing save to database.
Why do you do $auction->getPhotos()->add($auctionPhoto) ?
You should have a method addPhoto() or addAuctionPhoto() in your Auction entity, and use it like this:
$auction->addPhoto($auctionPhoto) or $auction->addAuctionPhoto($auctionPhoto)
EDIT:
Maybe your entity Auction is not the owner of the relation between the two entities, then you need to add $auctionPhoto->setAuction($auction), or if it's ManyToMany relation, then add $auctionPhoto->addAuction($auction)
Replace $auction->getPhotos()->add($auctionPhoto); with $auction->addPhoto($auctionPhoto);.
In your Auction entity, define the new method
// Auction.php
public function addPhoto(AuctionPhoto $thePhoto)
{
$this->photos[] = $thePhoto; // Add the photo to the object
$thePhoto->setAuction($this); // AuctionPhoto entity need to know about the reference
return $this; // Just for method chaining
}
(I assume $photos is your ArrayCollection which contains auction's photos)
Basically what you missed is to give a reference back to your entity:
$thePhoto->setAuction($this);
Are you saying nothing is in the database before you run this:
$em->persist($auction);
$em->flush();
If so, that is correct functionality. You need to persist then flush, then data is stored.

ZF2 + DoctrineORMModule + Boolean field

I'm setting up a form through annotations using
/**
* #ORM\Column(type="boolean", nullable=false, name="is_public")
* #Annotation\Required(false)
* #Annotation\AllowEmpty()
* #Annotation\Attributes({"placeholder":"Is Public"})
* #Annotation\Filter({"name":"boolean"})
* #Annotation\Options({"label":"Is Public"})
*/
private $isPublic;
This form is built using the doctrine annotation builder and the doctrine entity hydrator. The entity is then bound to this form. There is an issue when passing a boolean field, in that any value is treated as false, except 1, passing 0 results in an error message of "cannot be empty".
Can somebody please advise as to how I can use boolean fields properly using this method? Ideally I'd like to be able to use the filter before the field is validated? Not only that, but the validation is ignoring the AllowEmpty() and Required(false) fields.
Kind Regards,
ise
What you say is happening seems correct. Checkbox on forms submit nothing when unchecked, but the hydrator obviously needs to be able to know when the user intends to clear the value (mark false).
Pretty sure hydrator should work with empty string for false too. Required and AllowEmpty don't really make sense with a Boolean, especially in your case, because you also put nullable=false
This way I solved it $form->getInputFilter()->get('isPublic')->setContinueIfEmpty(true); just before $form->isValid()

Doctrine and ZF2

I am facing trouble using doctrine join. I can't share my code. But I can tell you scenario.
Please help me to achieve that.
I have created 2 entity. One User and Language.
User table is having foreign key language_id. and Language is master table with id and code fields.
I want to fetch user with some criteria, such a way it returns Language code from Language table as well.
I write join for that but it returns some full object...
Not sure how to fetch corresponding language code from Language table for language_id set in user table
If there is some example you know which can help me then also fine
i have return this in __construct()
$this->languageObj = new ArrayCollection();
when we print it is gives this
[languageObj:User:private] => Common\User\Entity\Language Object
(
[languageId:Language:private] => 1
[languageCode:Language:private] => en
[languageName:Language:private] => English
[languageCode2:Language:private] => User Object
RECURSION
)
I am not able to fetch languageCode from the object
You need methods defined in your entity to return the value from the object. It seems like everything is correct you would just need to grab the value from the entity. Here is an example:
$userEntity->getLanguageObj()->getLanguageId();
Your user Entity would need the getLanguageObj method which you can define like this:
public function getLanguageObj() {
return $this->languageObj;
}
And your Language Entity would also need a getLanguageId method:
public function getLanguageId() {
return $this->languageId;
}
Hope that helps!

Dropdown list in yii from other controller

I want list all objects of my model, and write to file the id of selected model. Using SiteController I render my page but what model I shall use?
$models = myModel::model()->findAll();
$list = CHtml::listData($models, 'id', 'name');
echo CHtml::dropDownList( ???? , $select, $list);
If I get what you're trying to do, You're talking about two models. Like tbl_product => Product and tbl_category => Category.
For demonstration purpose: Say, you want to create a new product and every product must belong to a category, then you might make use of the active dropdown. Using code similar to yours, you can say:
$category = Category::model()->findAll();
$list = CHtml::listData($category, 'id', 'name');
An important thing to note is that CHtml::activeDropDownList() expects different kinds of arguments. The main difference between it and CHtml::dropDownList() is that activeDropDownList( is tied to a Model while dropDownList() isn't.
public static string activeDropDownList(CModel $model, string $attribute, array $data, array $htmlOptions=array ())
public static string dropDownList(string $name, string $select, array $data, array $htmlOptions=array ())
So, using the example, assuming our Product model has a field called category_id, then the dropdown list would be generated using either:
CHtml::activeDropDownList($model, 'category_id', $list);
or if you've created an Activeform object like this:
$form=$this->beginWidget('CActiveForm');
then you could create the dropDown list like this:
$form->dropDownList($model, 'category_id', $list);
Where $model would be the Product model.
I hope this has been helpful.