DoctrineExtensions, does entity have translation in current locale? - php

I'm using DoctrineExtensions in order to get my entities translated. It works really fine, but i don't know how to resolve this issue :
I use translation fallback, personal translations and ORM query hint in order to reduce DB queries. If the translation doesn't exist, so it will fallback to default values. Till here, there's no problem.
But (this is my question) how could I know that entity has fallen back into the default values ? I mean, if an entity has no translation, is there a way to check it ?
For example, if we want to process this entity somehow whenever there's no translation. Something like :
if (!entity.isTranslated) {
//do something here
}
Of course, just for simplicity, we consider that all fields have been translated or not.
I hope I've been clear enough.
Thanks

I don't think you can do it for now (v2.*).
There is a big refactoring for v3.0, in Translatable there will be no default locale anymore.
See the pull request here: https://github.com/l3pp4rd/DoctrineExtensions/pull/764
no more default locale, all locales are persisted as translations, translatable entity fields serve only as proxy and representation

Related

Symfony 5.3 empty collection with a OneToMany relation

I have on my Symfony 5 project, 2 entities : Client and Template.
Each Client has one or more templates (OneToMany), each templates relates to only one Client (ManyToOne).
I have a getTemplates() function in Client.php which returns a Collection of templates.
The problem I am getting is that when I call the getTemplates() function I run it from :
$client = $entityManager->getRepository(Client::class)->find($id);
$templates = $client->getTemplates();
I am getting an initialized = false Collection.
From what I understand, to avoid unnecessary requests, Symfony creates a Template proxy object which is null.
To make this work, I can add fetch="EAGER"
#ORM\OneToMany(targetEntity=Template::class, mappedBy="Client", orphanRemoval=true, fetch="EAGER")
Adding this basically makes request the "real" Template object (more information here).
What I would like to do is make my getTemplates work without having to request all the templates when I retrieve all my clients like here (sometimes I only need to display all the clients, and request the templates from a certain client afterwards):
$templateRepository->findAll()
I know how to solve my problem, I just would like to have the best way to do it while having the smallest amount of requests to my database (basically only calling it when I need it).
To sum up, I would like to :
findAll() of my clients without retrieving the templates associated to the clients
findAll() of my templates and get the relating client - this currently works when I add a fetch="EAGER" since I get an "owner" which corresponds to the correct client
As Yassinefikri explained, the default Symfony behavior is not to request the linked Entities to avoid bad performance.
To solve the problem, you need a proper function in the repository where you will fetch the Clients and join them with their Templates.
This allows to fetch all the Clients without their Template but also be able to fetch all the Clients with their Templates, regarding of if you need it or not.
Changing the default behavior of Symfony by adding a fetch="EAGER" is not good practice, you should always create a function for a desired result instead of changing default behavior (which would decrease performance, specially if you are dealing with a big DB).
- EDIT, Better (and more optimized) way of solving the problem
As Will B said, the behavior comes from Doctrine ORM and not not Symfony (Symfony frequently is used with Doctrine ORM but this applies to ORM in general).
Another (and better) way of achieving the desired result is to initilialize the object (which will fetch linked entities without actually making JOIN requests to the DB - initializeObject()).
TO SUM UP
NEVER use fetch="EAGER" if you can since this is really the work way of dealing with linked entities, it is ay better to use Will B's or Yassinefikri's solution to the problem.

Where To Put Arrays For Common Data Storage In Symfony

I'm brand new to Symfony but am loving getting familiar with it (and many of the concepts behind it). MVC is pretty new to me in terms of the way I'm encountering it in Symfony.
My question is that if I have a simple array of commonly used data that I don't think necessarily belongs in a database table where should I store this. Is it an Entity? Should I store it in the Should I put it in the controller? Somewhere else?
I'm talking specifically about something like a US States array that I might use to power a dropdown. Right now I'm having to build an entity and store these in the database but would like to know if there is a better / preferred way to do this.
In my procedural days I would keep a file called "includes/arrays.php" and pull that when I needed one of these.
Thanks
If you want to use this data with other Entities, for example State would be connected to Adress object, I would stick with Entities, because it makes relations easier to implement and work with (I assume you using some kind of ORM e.g. Doctrine).
If you don't want to use this data with other entities, maybe you would like to hardcode them into all the templates somehow. http://symfony.com/doc/current/cookbook/templating/global_variables.html (I assumed you are using Twig).
A similar question was answered here:
Where to define static array related to an entity in symfony2 ?
It depends. I would opt by having that kind of data in the database. Suppose you in the future would have a back-office that update data.
Or you could use config files. For example, in yml format, arrays is easy to define.
Just like #foxtrot said, any data that is changeable should be stored in the database, just so you do not have to edit any code when a change occurs.
Firstly, I would create the Entity for the common data, and then I would use Fixtures to generate the entries in the database when you deploy your code.
This way, you allow later editing through either forms or phpMyAdmin, but you also get to write the default values into a PHP class so you don't have to manually enter all of them into the database.
See Symfony - DoctrineFixturesBundle

Doctrine2 - relation depending on parameter

I would like to know what is the best way to have an entity with 1:N relation to another entity but additionally depending on a parameter.
For example I have productentity and product_description entity, which depends on product_id and also on language (2 char code). Another examples would be manufacturer and manufacturer_description, category and category_description. There is a lot of it - you got the idea.
I though about extending EntityRepository class and adding automatic join based for example on an annotation. I'm just not sure if this is the "correct way" to do what I want. Can you suggest better solution? Another though was just to have method getDescription($language) in product entity but to me it just doesn't look as best solution, especially because I want to load the language-dependent content in 90% cases with all other information. Getting that content in separate query would just create unnecessary load.
Thank you for your suggestions.
There is a translatable extensions for doctrine. I've never used it but it looks like it might address your use case:
http://www.doctrine-project.org/2010/11/18/doctrine2-behavioral-extensions.html
See also
https://github.com/l3pp4rd/DoctrineExtensions

How to remove only one translation in CakePHP's TranslateBehavior?

I have a model with TranslateBehavior attached to it and I wonder if there is a method to remove only one translation of specific item and use only standard model methods (=not provide SQL query on i18n table explicitly, because I want to be absolutely independent of DB engine) and not set it blank but really remove.
Simple situation example:
There is an article in DB with translations in English and German. One day editor decides not to provide this article in German and wants to remove it from DB (but English version should be still available). And now appears the question I wrote above.
Thank you in advance for your help.
As for now after examining afterSave callback in the behavior class I see only some kind of workaround - to use the core model I18nModel defined in cake/libs/model/behavior/translate.php (bottom of the file) and use delete method with manually set all conditions that normally are set by translateBehavior.
The I18nModel model can be used in standard way:
var $uses = array('SomeModelUsingTranlateBehaviour','I18nModel');

Generated Doctrine models respect case, but generated Yaml does not

Just getting started with Doctrine ORM for PHP (v1.1.5) and ran into something unexpected.
I am generating models from the db (MySQL 4) using:
Doctrine::generateModelsFromDb($pathToModels);
Then generating YAML from the models using:
Doctrine::generateYamlFromModels($pathToSchema . '/schema.yml', $pathToModels);
In the generated models, the column names (as defined in hasColumn()) use the same case for the fields as in the db. All good.
But in the generated YAML, the column names are all lower-case, irrespective of the case in the model.
There do not seem to be any options available on the generateYamlFromModels() method that I could conceivably use to tweak this. Is there some other attribute I should be setting someplace, perhaps at connection-level, or at manager-level, etc? Might it be a bug?
Any ideas greatly appreciated. Thanks and cheers!
It seems this is a bug. I say that because YAML is case sensitive, and Doctrine's generateYAMLFromModels() is documented to be case sensitive. I did find a case sensitivity bug that was in 2.0 beta. Maybe this is the bug that affected your program. Barring anything else, though, it looks like Dimitris Baltas' comment seems to be the the workaround of choice:
an other alternative is to generate models from DB and then yaml from models. This one keeps the right casing.
Happy Hunting :)

Categories