Some property object are null - symfony

I have a problem and of course i dont understand :) (and of course im french :)
On a table "evenement" i have a user linked.
And When i do :
$repository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Evenement');
$evt = $repository->findOneById($evt);
dump($evt)
All is ok, i can read my evt, but when in profiler i click on a child object "user", all property are null (except id, usermail, mail, password)
and its the same thing when i do :
dump($evt->getUser());
Why all property are not filled ?
thank you and sorry for my english.

It's most probably Lazy Loading. Properties are not beeing read from DB unless you need them.
Try to do the following:
$repository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Evenement');
$evt = $repository->findOneById($evt);
$evt->getUser()->getRoles(); // Ot whatever properties your user has.
dump($evt)
In this case, dump will show this property populated.

Related

Datasource Paging Issue (Revised Again)

See Datasource Paging Issue (Revised)
for the original question.
Markus, you were kind enough to help with out with the issue of incorporating a record count into a query using a calculated datasource. I have a search form with 15 widgets - a mix of date ranges, dropdowns, text values and ._contains, ._equals, ._greaterThanOrEquals, ._lessThanOrEquals, etc.
I have tested this extensively against mySQL SQL code and it works fine.
I have now added a 16th parameter PropertyNames, which is a list with binding #datasource.query.filters.Property.PropertyName._in and Options blank. The widget on the form is hidden because it is only used for additional filtering.
Logic such as the following is used, such that a particular logged-in user can only view their own properties. So if they perform a search and the Property is not specified we do:-
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = params.param_PropertyNames;
}
The record count (records.length) is correct, and if I for loop through the array of records the record set is correct.
However, on the results page the table displays a larger resultset which omits the PropertyNames filter. So if I was to search on Status 'Open' (mySQL results 50) and then I add a single value ['Property Name London SW45'] for params.param_PropertyNames the record count is 6, the records array is 6 but the datasource display is 50. So the datasource is not filtering on the property array.
Initially I tried without adding the additional parameter and form widget and just using code such as
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = properties; // an array of
properties to filter out
}
But this didn't work, hence the idea of adding a form widget and an additional parameter to the calculated recordcount datasource.
If I inspect at query.parameters then I see:-
"param_Status": "Open",
"param_PropertyNames": ["Property Name London SW45"],
If I inspect query.filters:-
name=param_Status, value=Open
name=param_PropertyNames, value=[]}]}
It looks as though the filter isn't set. Even hard coding
ds.filters.Property.PropertyName._in = ['Property Name London SW45'],
I get the same reuslt.
Have you got any idea what would be causing this issue and what I can do for a workaround ?
Using a server side solution I would suggest editing both your SQL datasource query script (server side) that is supposed to filter by this property list and including the same code in your server side script for your calculated Count datasource. The code would look something like this, not knowing your exact details:
var subquery = app.models.Directory.newQuery();
subquery.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
subquery.prefetch.Property._add();
var results = subquery.run();
if(!results[0].CanViewAllRecords) {
query.filters.Property.PropertyName._in = results[0].Property.map(function(i) {return i.PropertyName;});
}
By adding this code you are filtering your directory by your current user and prefetching the Property relation table, then you set the filter only if your user canviewallRecords is false and use JS map function to create an array of the PropertyName field in the Property table. As I stated, your code may not be exactly the same depending on how you have to retrieve your user canviewallrecords property and then of course I don't know your relation between user and Property table either, is it one-to-many or other. But this should give you an idea how to implement this on server side.

Hooks: processDatamap_preProcessFieldArray()

I am about porting an Extention from T3-6.2 to T3-7.6+
public function processDatamap_preProcessFieldArray(
&$fieldArray, $table, $id,
\TYPO3\CMS\Core\DataHandling\DataHandler &$pObj
) {
// t3_origuid is set? Yes, ist a Copy
if(isset($fieldArray['t3_origuid']) && $table=='mytable') {
$fieldArray['field1']++;
$fieldArray['filed2']--;
}
}
BUT:
To tell if it is a copy or not this needs the field 't3_origuid' in my record. It is not a standard field but if present it is filled by typo3.
Where does this filed come from? My I use this witout further problems?
If you know a hook/better way, (Slot, Signal?) to use in this case in T3 7.6+ please let me know.
Thanks a lot,
Christian.
This field is used by the sys extension workspace. If you change a tt_content element inside a workspace the original uid will be stored inside the field. So the changes,when they will be published, can be applied to the original element.

Trouble converting Google App Maker from draft record in datasource

I see that the draft record in datasource is deprecated. I read the release notes but am having trouble with one bit of code. Tried to convert this:
widget.datasource.draft.Email = (newValue) ? newValue.PrimaryEmail : null;
to this:
widget.datasource.item.Email = (newValue) ? newValue.PrimaryEmail : null;
But am getting this error: Cannot set property 'Email' of null
Any suggestions on what is wrong? The widget is being passed from the onValueChange action.
Thanks
You can change the widget's datasource to the create datasource in the Property Editor on the right side. Click the datasource binding and select "[Datasource Name] (create)". (screenshot)
An alternative option if you want to keep your widget bound to the normal datasource would be to set it programmatically:
widget.datasource.modes.create.item.Email = (newValue) ? newValue.PrimaryEmail : null;
Here is further documentation for accessing the create datasource through scripting.
I believe you need to set your widget's data source to a "Create" data source, before converting to "item".

How to do empty list check in maximo anywhere

I am getting few json response from service as "-##EmptyComplexField##-". Due to which screen crashes. How to do a proper empty check for complex feild in maximo anywhere. Please help with sample code.
We can do a empty check for list as below
if(list && list!="-##EmptyComplexField##-")
Not sure why you're getting this EmptyComplexField string down at your layer. Are you sure you've defined your multiplicity correctly on the OSLC Resources app for these new children objects?
if (/-or-many$/.test(complexAttribute.multiplicity)){
var attributeName = complexAttribute.remoteName;
if (!(attributeName in data)){
Are you making sure these complexattributes are set as requiredattributes on the view before you display it?
The most correct answer would be:
if (list && list != PlatformConstants.EMPTY_COMPLEX_FIELD) { ... }

How does Entity Framework decide whether to reference an existing object or create a new one?

Just for my curiosity (and future knowledge), how does Entity Framework 5 decide when to create a new object vs. referencing an existing one? I might have just been doing something wrong, but it seems that every now and then if I do something along the lines of:
using (TestDB db = new TestDB())
{
var currParent = db.Parents.Where(p => p.Prop == passedProp).FirstOrDefault();
if(currParent == null) {
Parent newParent = new Parent();
newParent.Prop = passedProp;
currParent = newParent;
}
//maybe do something to currParent here
var currThing = db.Things.Where(t => t.Prop == passedPropTwo).FirstOrDefault();
currThing.Parent = currParent;
db.SaveChanges();
}
EF will create a new Parent in the database, basically a copy of the currParent, and then set the Parent_ID value of currThing to that copy. Then, if I do it again (as in, if there's already two of those parents), it won't make a new Parent and instead link to the first one. I don't really understand this behavior, but after playing around with it for a while something like:
using (TestDB db = new TestDB())
{
var currParent = db.Parents.Where(p => p.Prop == passedProp).FirstOrDefault();
if(currParent == null) {
Parent newParent = new Parent();
newParent.Prop = passedProp;
currParent = newParent;
}
//maybe do something to currParent here
var currThing = db.Things.Where(t => t.Prop == passedPropTwo).FirstOrDefault();
currThing.Parent = db.Parents.Where(p => p.ID == currParent.ID).First();
db.SaveChanges();
}
seemed to fix the problem. Is there any reason this might happen that I should be aware of, or was there just something weird about the way I was doing it at the time? Sorry I can't be more specific about what the exact code was, I encountered this a while ago and fixed it with the above code so I didn't see any reason to ask about it. More generally, how does EF decide whether to reference an existing item instead of creating a new one? Just based on whether the ID is set or not? Thanks!
If your specific instance of your DBContext provided that specific instance of that entity to you, then it will know what record(s) in the database it represents and any changes you make to it will be proper to that(those) record(s) in the database. If you instantiate a new entity yourself, then you need to tell the DBContext what exactly that record is if it's anything but a new record that should be inserted into your database.
In the special scenario where you have multiple DBContext instances and one instance provides you this entity but you want to use another instance to work with and save the entity, then you have to use ((IObjectContextAdapter)firstDbContext).ObjectContext.Detach() to orphan this entity and then use ((IObjectContextAdapter)secondDbContext).ObjectContext.Parents.Attach() to attach it (or ApplyChanges() if you're also editing it - this will call Attach for you).
In some other special scenarios (your object has been serialized and/or you have self-tracking entities), some additional steps may be required, depending on what exactly you are trying to do.
To summarize, if your specific instance of your DBContext is "aware" of your specific instance of an entity, then it will work with it as if it is directly tied to that specific row in the database.

Resources