Expecting ParentFieldArray to be an array or object but it is a string 'fields'

I am attempting to implement calculated fields as a field type in SuiteCRM
but I’m stuck trying to find the best place to set the value.

As I want this field type to work in the V8 API, Email Templates, and the GraphQL endpoint, I can’t just set the value as a random variable in the Smarty Template as from what I understand that would only work if the field went through the Smarty Engine aka rendered for the web application UI.
I won’t be able to put it in the save function because then the values would only be calculated when the bean changes.

I thought about using the formatField function but this isn’t used by default \ called when a fields value is requested.

whilst going through the SugarField stuff I found an undocumented variable which is a different type to what it is suppose to be.

$ParentFieldArray which is always set as a string ‘field’,
I saw in the SugarFieldBase class that if this variable was either an array or an object, then Suite will attempt to format the values,

does anyone know where ParentFieldArray is set or where in the system a fields value is generated?

This is all very similar to what I did for PowerFields and PowerReplacer add-ons (https://pgorod.github.io/suitecrm-add-ons/)

The answer is that you won’t be able to do it from a single point. There are several flows and you need to launch your code from more than one place.

And I didn’t even touch the API or GraphQL stuff, although I’m not sure what you mean by Calculated fields in this context. If it’s just an operation that runs on record creation or record modification, then ok, the flows from the Bean object will catch that. But they won’t intervene for output.

What I meant by calculated fields is a field type that would allow for mathematical expressions to be defined for a field in studio (take values from these fields and do something with them to generate a value).
similar to calculated fields in AOW except without the need for a workflow.

Yep, that’s one the things that PowerFields does. You can set formulas for the field in Studio.: one for Create and one for Modify events. Then that formula can reference the value in the field as a variable, to use it in calculations and transformations.

I think the thing you need to keep in mind to clarify your design is this: in which moment does the calculation take place? Because in the case I described above, it is in Bean save action. But you mentioned API’s, templates… those are different moments.

That’s pretty cool,

To not go around in circles, I will describe what I believe happens when the CRM system is fetching values for whatever purpose if it is the API, a view in the UI or the GraphQL Endpoint in V8

so we have a DAO our data access object, in this case it is a sugar bean.
the values for a bean must come from somewhere and by default they mostly come from the database table that is associated with the bean.
And there are some values which do not come from the beans table like for example the name and id of the assigned user.

I see the CRM system using the field type files to understand how to generate the values which are used by the API, GraphQL Endpoint, UI, or email template

But I don’t actually know where or how this is done (
does each of the aforementioned paths work in completely different ways and have
different code all fetching values but in slightly different ways?
or perhaps it is written in such a way that every field value is expected to come from the database

I really do hope there is just the one central/singular way of getting a field value

You’re thinking in terms of calculate-upon-output of field, I’ve always thought in terms of calculate-on-save.

Well, for templates I also worked on output.

It’s likely you might find a nice spot for your approach somewhere in SugarBean object, but it surely won’t be effective everywhere, there’s a lot of specific code in many places because of direct SQL, construction of complex queries, filters affected by UI options, etc.

But you might be able to find a spot that is reasonably effective for (most of) your purposes.

Are you using a debugger with XDEBUG and an IDE such as PhpStorm or Eclipse? That way to do this is to really dig into the stack trace, understand the full flow (of an API query, for example) and see where it grabs the data. Then see if that can be extended in an upgrade-safe manner (which can get tricky sometimes when you are very near the core of the core).