Retrieve annotations and propreties - symfony

I have multiple #groups({"group1","group2"}) annotations in my entities , I want to know if there is a way to retrieve the groups in order to use them .
i.e : An array of all the groups mentionned in a certain entity

You must use the SPL library PHP for do this.
In particular the reflectionClass. It seems that has method for inspect all the DocBlock in class.
You can read this for more understand : ReflectionClass::getDoccomment
for have a little idea of implementation you can inplement this kind of code :
function getAnnotations($class)
{
$inspectedClass = new ReflectionClass($class);
$inspectedClassDoc = $inspectedClass->getDocComment();
}

Related

How do I get the sys_language_uid with extbase

In TYPO3 9.5 is only $GLOBALS['TSFE']->sys_language_isocode available. How do I get the numeric sys_languagae_uid in my controller?
You can use the new Context singleton for this:
$context = GeneralUtility::makeInstance(Context::class);
return (int)$context->getPropertyFromAspect('language', 'id');
This will return the numerical "sys_language_uid". When you look into the docblock of the Context class (see public/typo3/sysext/core/Classes/Context/Context.php, there is also a list of possible aspects you may use. There also is a documentation available.

symfony 4 with fixtures, the getReference method does not return the expected object (return PROXY/__CG__/... instead an instance of User class)

From symfony 4, I created two fixtures classes.
When I run the command "./bin/console doctrine:fixtures:load" I get this error :
Argument 1 passed to App\Entity\Article::setAuthor() must be an instance of User, instance of Proxies\__CG__\App\Entity\User given, called in /home/okli/PhpstormProjects/nomads_fiction/src/DataFixtures/ArticleFixtures.php on line 53
From the fixture 1 (the first fixture called), I created a user with this code :
$myuser = new User();
$myuser->setName("foo");
...
$em->persist($myuser);
$em->persist();
$this->addReference("foo", $myuser);
$this->log->info("class is : " . get_class($myuser)); // print "class is : App\Entity\User" its good !
From the fixture 2, I loaded the myuser object like this :
$myuser = $this->getReference("foo");
$this->log->info("class is : " . get_class($myuser)); // print "class is : Proxies\__CG__\App\Entity\User", why not App\Entity\User ?
Why getReference doesn't return me the exact same object I returned from the fixture 1 ? Where is my mistake ?
Thank you for some help :)
That's exactly what it was supposed to do. The getReference() function lets you obtain a reference to an entity for which the identifier is known, without loading that entity from the database, which is a proxy object of the generated class for the User. Full documentation here
In fact, doctrine doesn't really care if you use a proxy object. All you have to do to get your code working is to remove the type-hinting from the setAuthor function in Article entity (i.e setAuthor(User $user) to setAuthor($user)).
This will work because all you want to achieve by calling the setAuthor function is to establish an association to an entity. Since you already have the identifier for this entity, you don't have to fully load it.
EDIT: As Matías Navarro Carter observed, entity proxy classes extend real entity classes, so the type-hinting should work anyway. I guess you forgot to use the appropriate namespace in your Article entity. Maybe you are missing something like this in your Article.php:
use App\Entity\User;

getViewData vs. getNormData and DataTransformers - different results depending on context

I have a form with several fields.
Then I bound DataTransformer to the one of them. Transformer works correctly if I get data getViewData and getNormData.
But if I issue these methods on whole form, data processed by transformers are completely ignored.
In Form data is being overwritten due to the:
$childrenIterator = new InheritDataAwareIterator($this->children);
$childrenIterator = new \RecursiveIteratorIterator($childrenIterator);
$this->config->getDataMapper()->mapFormsToData($childrenIterator, $viewData);
My mapper is PropertyPathMapper. Unfortunately, it bases on getData method of each child.
Is it possible to bypass viewData overwrite / achieve correctly transformed data without writing a global transformer?
a workaround:
$data = array();
foreach ($form->all() as $k => $el) {
$data[$k] = $el->getData(); // or getNormData or getViewData
}
Unfortunately I have no solution.
The current behaviour is not what I expected. It should at least be mentioned in the symfony cookbook.
As you see I have the same problem. I wrote a test case to be sure that I do not misunderstand how the transformers work. I found your question later.
my test case:
https://github.com/SimonHeimberg/SymfonyFormForm_DataTransformer_Demo

Doctrine2 ignore undefined discriminator classes

While using the doctrine2 "class table inheritance" to schedule events of different types.
Hypothetical scheme:
This is all fine but the fact is that - because of our modular in-house system - some classes could be "unregistered" from the discriminator map (in cache?).
When this happens the findAll will throw an exception telling us he cannot find the correct object mapping.
So the option i thought of were:
Rewrite the repository methods (findOne, findBy, etc.) to add a filter to the query.
$discrClasses = array();
foreach($this->_em->getMetadataFactory()->getAllMetadata() as $class) {
$discrClasses[] = $class->getName();
}
$discrQuery = sprintf('f.discr INSTANCE OF (%s)', implode(',', $discrClasses));
My question is: is this the right way to handle this or is there a better solution?

LINQ and web service cannot return anonymous types, and you cannot construct an object in a query?

Web services cannot return an anonymous type.
If you are building a LINQ query using classes through a datacontext... you cannot construct instances of those classes in a query.
Why would I want to do this? Say I want to join three "tables" or sets of objects. I have three items with a foreign key to each other. And say the lowest, most detailed of these was represented by a class that had fields from the other two to represent the data from those. In my LINQ query I would want to return a list of the lowest, most detailed class. This is one way I have decided to "join some tables together" and return data from each of them via LINQ to SQL via a WebService. This may be bad practice. I certainly do not like adding the additional properties to the lowest level class.
Consider something like this... (please ignore the naming conventions, they are driven by internal consideration) also for some reason I need to instantiate an anonymous type for the join... I don't know why that is... if I do not do it this way I get an error...
from su in _dataContext.GetTable<StateUpdate>()
join sfs in _dataContext.GetTable<SystemFacetState>()
on new { su.lngSystemFacetState } equals new { lngSystemFacetState = sfs.lngSystemFacetState }
join sf in _dataContext.GetTable<SystemFacet>()
on new { sfs.lngSystemFacet } equals new { lngSystemFacet = sf.lngSystemFacet }
join s in _dataContext.GetTable<System>()
on new { sf.lngSystem } equals new {lngSystem = s.lngSystem}
select new
{
lngStateUpdate = su.lngStateUpdate,
strSystemFacet = sf.strSystemFacet,
strSystemFacetState = sfs.strSystemFacetState,
dtmStateUpdate = su.dtmStateUpdate,
dtmEndTime = su.dtmEndTime,
lngDuration = su.lngDuration,
strSystem = s.strSystem
}
).ToList();
Notice I have to build the anonymous type which is composed of pieces of each type. Then I have to do something like this... (convert it to a known type for transport via the web service)
result = new List<StateUpdate>(from a in qr select(new StateUpdate
{
lngStateUpdate = a.lngStateUpdate,
strSystemFacet = a.strSystemFacet,
strSystemFacetState = a.strSystemFacetState,
dtmStateUpdate = a.dtmStateUpdate,
dtmEndTime = a.dtmEndTime,
lngDuration = a.lngDuration,
strSystem = a.strSystem
}));
It is just awful. And perhaps I have created an awful mess. If I am way way off track here please guide me to the light. I feel I am missing something fundamental here when I am adding all these "unmapped" properties to the StateUpdate class.
I hope someone can see what I am doing here so I can get a better way to do it.
You can create a 'dto' class which just contains the properties you need to return and populate it instead of the anonymous object:
public class Result
{
public string lngStateUpdate
{
get;
set;
}
... // other properties
}
then use it like this:
from su in _dataContext.GetTable<StateUpdate>()
...
select new Result
{
lngStateUpdate = su.lngStateUpdate,
... // other properties
}
Nitpick note - please ditch the Hungarian notation and camel casing for properties :)
I think the answer is to create another object to serve as a DTO. This object would not be mapped to the data context and can contain fields that cross the mapped objects. This solves the problems of repetitive properties in the mapped objects, and allows for instantiation of the DTO class in the query as it is not mapped.
FYI: with respect to the problem with the join- I revisited that and I think I may have had the inner and outer components of the join switched around before.

Resources