Important
You are browsing upcoming documentation for version 6.1 of OroCommerce, scheduled for release in 2025. Read the documentation for version 6.0 (the latest LTS version) to get up-to-date information.
See our Release Process documentation for more information on the currently supported and upcoming releases.
EntityStructureDataProvider
EntityStructureDataProvider:
provides access over EntityStructuresCollection to EntityStructure API.
shares the same instance of EntityStructuresCollection between providers
contains a pack of helper methods to filter and navigate across entity relations
Get the EntityStructureDataProvider instance
Static method createDataProvider of EntityStructureDataProvider allows to get the provider’s instance:
import EntityStructureDataProvider from 'oroentity/js/app/services/entity-structure-data-provider';
// ...
initialize(options) {
var providerOptions = {
rootEntity: 'Oro\\Bundle\\UserBundle\\Entity\\User'
};
EntityStructureDataProvider
.createDataProvider(providerOptions, this)
.then(provider => this.provider = provider);
}
The signature for createDataProvider method is the following:
/**
* Creates instance of data provider and returns it with the promise object
*
* @param {Object=} options
* @param {string} [options.rootEntity] class name of root entity
* @param {string} [options.filterPreset] name of filter preset
* @param {Object.<string, boolean>} [options.optionsFilter] acceptable entity's and fields' options
* example:
* {auditable: true, configurable: true, unidirectional: false}
* @param {[Object|string]} [options.exclude]
* examples:
* ['relationType'] - will exclude all entries that has 'relationType' key (means relational fields)
* [{type: 'date'}] - will exclude all entries that has property "type" equals to "date"
* @param {[Object|string]} [options.include]
* examples:
* ['relationType'] - will include all entries that has 'relationType' key (means relational fields)
* [{type: 'date'}] - will include all entries that has property "type" equals to "date"
* @param {fieldsFilterer} [options.fieldsFilterer]
* @param {boolean} [options.isRestrictiveWhitelist] - says if only fields from whitelist
* has to be represented in results
* @param {Object.<string, Object.<string, boolean>>} [options.fieldsFilterWhitelist]
* whitelist of fields that has NOT to be filtered out
* examples:
* {'Oro\\Bundle\\UserBundle\\Entity\\User': {groups: true}} - groups field of User entity
* has to be included to results, despite it might not pass the filters
* @param {Object.<string, Object.<string, boolean>>} [options.fieldsFilterBlacklist]
* blacklist of fields that HAS to be filtered out
* examples:
* {'Oro\\Bundle\\UserBundle\\Entity\\User': {groups: true}} - groups field of User entity
* has to be excluded from results, despite it might pass the filters
* @param {Object.<string, Object.<string, Object>>} [options.fieldsDataUpdate]
* data update that has to be applied to fields of filtered results
* examples:
* {'Oro\\Bundle\\UserBundle\\Entity\\User': {
* groups: {type: 'enum'}, // groups field of User entity will be represented as enum
* viewHistory: {type: 'collection', label: 'View history'} // new field will be added
* }}
* @param {RegistryApplicant} applicant
* @return {Promise.<EntityStructureDataProvider>}
*/
createDataProvider: function(options, applicant) { ... }
Where the first argument is the options for the provider:
rootEntity class name of the entity where navigation by fields and relations starts from
optionsFilter, exclude and include rules allow to define constraints for the entities and the fields that the provider returns
fieldsFilterer custom filter function
filterPreset name of the preconfigured filter
isRestrictiveWhitelist defines mode of whitelist, by default it is not restrictive
fieldsFilterWhitelist and fieldsFilterBlacklist allows to define filter strategy for specific fields
fieldsDataUpdate allows to define updates for filtered data
And the second argument is the applicant (who the structure is requested for). It allows to define life cycles of shared EntityStructuresCollection instance in registry (see registry for details).
The method works asynchronously, it returns provider instance within promise. The promise assures the instance EntityStructuresCollection of the provider already contains fetched data from the server and the provider is ready to use.
Define Filter’s Preset
It is common for several providers to use the same filter configuration. For such cases, you can define filter preset:
EntityStructureDataProvider.defineFilterPreset('workflow', {
optionsFilter: {unidirectional: false, configurable: true},
exclude: [
{relationType: 'manyToMany'},
{relationType: 'oneToMany'}
]
});
Once the preset is defined, its name can be used to configure the provider:
EntityStructureDataProvider
.createDataProvider({
filterPreset: 'workflow',
include: [{type: 'date'}, {type: 'datetime'}]
}, applicant)
The direct definition of fieldsFilterer, optionsFilter, exclude and include options have higher priority over the defined onr in used filterPreset. This allows to customize filter configuration for a certain provider.
Entity tree
Data provider has magic property entityTree that returns linked objects. It allows to navigate over entities and their relations.
console.log(provider.entityTree);
{ // list with enumerable entities
user: (...),
organization: (...),
userrole: (...)
// ...
}
console.log(provider.entityTree.user);
{ // list with enumerable fields of user entity
id: (...),
firstName: (...),
roles: (...)
// ...
}
console.log(provider.entityTree.user.roles);
{ // list with enumerable fields of userrole entity
id: (...),
label: (...),
// ...
}
console.log(provider.entityTree.user.roles.label);
{} // object of non-relation field has no enumerable properties
- Each tree node can represent entity or/and field:
root nodes are only entities
leaf nodes are only fields
intermediate nodes are both fields and entities, since they represent relation fields
All nodes have magic properties __isField and __isEntity.
// root nodes are entity
console.log(provider.entityTree.user.__isEntity); // true;
console.log(provider.entityTree.user.__isField); // false;
// relation-field nodes are both fields and entities
console.log(provider.entityTree.user.roles.__isEntity); // true;
console.log(provider.entityTree.user.roles.__isField); // true;
// leaf nodes are field
console.log(provider.entityTree.user.roles.label.__isEntity); // false;
console.log(provider.entityTree.user.roles.label.__isField); // true;
Field nodes have magic property __field, that returns information about the field.
// relation field
console.log(provider.entityTree.user.roles.__field);
{
label: 'Roles',
name: 'roles',
relationType: 'manyToMany',
relatedEntityName: 'Oro\\Bundle\\UserBundle\\Entity\\Role',
parentEntity: {
label: 'User',
alias: 'user',
className: 'Oro\\Bundle\\UserBundle\\Entity\\User',
fields: [ /* ... */ ]
// ...
},
relatedEntity: {
label: 'Role',
alias: 'userrole',
className: 'Oro\\Bundle\\UserBundle\\Entity\\Role',
fields: [ /* ... */ ]
// ...
}
// ...
}
// non-relation field
console.log(provider.entityTree.user.roles.label.__field);
{
label: 'Label',
name: 'label',
type: 'string',
parentEntity: {
label: 'Role',
alias: 'userrole',
className: 'Oro\\Bundle\\UserBundle\\Entity\\Role',
fields: [ /* ... */ ]
// ...
}
// ...
}
Entity nodes have magic property __entity, that returns information about the entity.
console.log(provider.entityTree.user.__entity);
{
label: 'User',
alias: 'user',
className: 'Oro\\Bundle\\UserBundle\\Entity\\User',
fields: [ /* ... */ ]
// ...
}
console.log(provider.entityTree.user.roles.__entity);
{
label: 'Role',
alias: 'userrole',
className: 'Oro\\Bundle\\UserBundle\\Entity\\Role',
fields: [ /* ... */ ]
// ...
}
Get EntityTreeNode by property path
There’s method getEntityTreeNodeByPropertyPath in EntityStructureDataProvider allows to get the node by property path string
const node = provider.getEntityTreeNodeByPropertyPath('user.roles.label');
console.log(node.__isField); // true
console.log(node.__isEntity); // false
console.log(node.__field);
{
label: 'Label',
name: 'label',
type: 'string',
parentEntity: {
label: 'Role',
alias: 'userrole',
className: 'Oro\\Bundle\\UserBundle\\Entity\\Role',
fields: [ /* ... */ ]
// ...
}
// ...
}
See other methods of oroentity/js/app/services/entity-structure-data-provider.