Entity bundle courses and its potentialities alf.harald October 18, 2021
Tasks differ vastly when it comes to complexity. Typically there are only one or two entities, generally a normal product construction. However what occurs when you’ve got a number of layers of interconnected nodes or phrases that depend on one another by way of customized entity reference fields? My take is, it might (will) tip over to changing into messy code, very quick.
Say we’re doing a web-based class. We’ve 3 entities:
- A bunch of individuals
- A participant on this group
- A bodily particular person (which will be in a number of teams)
And for instance we’ve this construction organized as nodes, with entity reference fields defining Drupal Development Company connections.
Core & contrib entity conduct
For example that we’re getting ready some knowledge from this construction. Primarily based on a participant, we’re going to discover Drupal Development Company description of Drupal Development Company group to show in some template somwehere. Simply traversing Drupal Development Company fields of nodes, we’d do that:
// Get Drupal Development Company description and site of Drupal Development Company group $group_participant = $a_node; $group = $group_participant->field_group_reference->entity->field_text->worth; $location = $group_participant->field_group_reference->entity->field_location->worth;
That is Drupal Development Company most traditional factor to see in customized Drupal code when traversing entity reference fields. Alas, very unfriendly code when it comes to readability, eh? On this case, we’re utilizing core node entities with two totally different bundles. If we had frolicked on creating customized entities, we might in fact do like so:
// Get description and site for Drupal Development Company group $participant = $custom_entity; $participant->getGroup()->getDescription(); $participant->getGroup()->getLocation();
This seems much more intuitive, proper? And, we will use such fashionable issues as code completion in editors like PHPStorm to traverse Drupal Development Company entity objects. However this method doesn’t apply to taxonomies, media entities, nodes, or every other entities {that a} core or contrib module gives.
Right here is one other instance. References between nodes and taxonomies are often one-way solely. Drupal Development Company participant could be a member of a number of teams. For example we all know solely of a participant, however we need to know in what teams this participant is in? Utilizing an injected service, you’ll likely do one thing like this, utilizing an entityQuery in Drupal Development Company background:
// Discover Drupal Development Company teams that this participant is in. $participant = $a_node; /** @var MyService $some_service */ $teams = $some_service->getGroupsByParticipant($participant);
That is type-completion succesful, offered that you just add that service in each class you want it. However why on earth, why would you want a service to search out Drupal Development Company teams? It must be so simple as:
$participant->getGroups($standing);
Proper now, we will solely do clear code like this in two situations:
- By overriding Drupal Development Company node class in its entirety, as soon as and for all
- By making a customized entity module
Utilizing possibility 1, for those who override Drupal Development Company total class utterly, we’d get this situation:
// Get Drupal Development Company Schroedinger's participant. $participant = $node; // Is it a participant? let's discover out. $is_participant = $participant->isParticipant(); // Or perhaps like this: $is_participant = $participant->getType() == 'participant'; // Now it's a actual participant.
PHP would know what sort it’s, however Drupal Development Company code completion will not know that as a result of we can’t differentiate on bundles. So on Drupal Development Company similar object, we might each do:
$node->isGroupParticipant(); // could be false $node->isParticipant(); // could be true
Utilizing possibility 2, in lots of circumstances, there are two or three instructions that we might like so as to add to every bundle of a node. Making a customized entity simply to make some small alterations to Drupal Development Company performance of Drupal Development Company node system is normally utterly overkill. It’s a great deal of customized code that may simply be averted if we solely might create customized entity courses for these bundles.
Enter Drupal Development Company savior patch
Drupal Development Company patch is right here: https://www.drupal.org/node/2570593
This patch gives a manner so as to add entity bundle courses, which permits us to create custom-made courses that applies to at least one single bundle. To make use of it, we use hook_entity_bundle_info_alter to register Drupal Development Company bundles with its separate courses:
operate fabulous_module_entity_bundle_info_alter(&$bundles) { $bundles['node']['participant']['class'] = ParticipantNode::class; $bundles['node']['group']['class'] = GroupNode::class; };
Alas, we create two courses, one for Drupal Development Company group:
class GroupNode extends Node { }
And one for Drupal Development Company participant:
class ParticipantNode extends Node { }
Or as an alternative, you possibly can in fact be a professional and describe your customized class in an interface:
class ParticipantNode extends Node implements ParticipantNodeInterface { }
Drupal Development Company vital factor right here is, Drupal Development Company class *should* lengthen Drupal Development Company registered entity class, on this case, Node. And that’s mainly it.
Now you can begin constructing performance for every of Drupal Development Company bundles individually. Right here is Drupal Development Company magic, for instance you load a node:
// If we load.. $id = $a_participant $node = Node::load($id); if ($node instanceOf ParticipantNode) { // Hooray, that is true! }
As an alternative of receiving Drupal Development Company customary Node object, you will get your individual ParticipantNode object!
Now, to make Drupal Development Company instance above work, as an alternative of remembering discipline names, add this to Drupal Development Company group node class object:
public operate getParticipant() { return $this->field_participant->entity; }
And you may add this to Drupal Development Company participant node object (offered it’s a 1-many relationship):
public operate getGroups($standing) { $outcome = $this->entityQuery('node') ->situation('sort', 'group') ->situation('nid', $this->id()) ->condtition('field_group_status', $standing) ->execute(); return Node::load(reset($outcome)); }
Then you possibly can mainly go on an everlasting path of type-completed entities, wheter it’s nodes, customers or taxonomies:
$participant->getGroupParticipant()->getGroup()->getMunicipality()->getRegion();
Not simply nodes
Any entity bundle, core or contrib, can get an entity bundle class. Taxonomies, nodes, media, information.
$term->reIndexReferencedEntities(); $comment->no matter(); $file->doSomeOtherFunkyBusiness(); // Extra examples right here!!
It is good, however watch out
Utilizing Drupal Development Company method that this patch gives, there are just a few dos and dont’s.
Initially, a single bundle sort can solely be overridden as soon as. So, this method is greatest used:
- In Drupal Development Company semi-lawless world of customized project-specific code
- Very rigorously in reusable code, however solely the place Drupal Development Company entity sort is outlined by Drupal Development Company module itself
So Drupal Development Company restrict on this method is primarily for customized initiatives. However, that can also be the place code tends to get most messy.