Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Comment | File | Size | Author |
---|---|---|---|
#65 | group-computed-fields-2718195-65.patch | 11.28 KB | lexhouk |
#61 | group-computedfields-2718195-60.patch | 9.2 KB | hitesh-jain |
#60 | group-computedfields-2718195-58.patch | 9.2 KB | hitesh-jain |
#59 | group-2718195-58-groups-computed-field.patch | 9.11 KB | Henry Tran |
Comments
Comment #2
joachim CreditAttribution: joachim commentedAfter a bit of thought about this, it seemed to me that a computed entityreference field would be better here.
We'd get the entityreference field formatters for free, along with access control to the group entities.
However, while I can define the field, see it in the node field display UI, it doesn't output anything on nodes. The entityreference field formatter class is called for the computed field, but $items is empty.
So tte basic problem is that I don't see where to actually tell the field what its computed value is.
I've got this:
I've tried adding
to that, but that has to be a class that inherits from EntityReferenceFieldItemList, but it's EntityReferenceItem which AFAICT actually returns a value.
I've also tried making a custom entity type, which inherits from EntityReferenceItem, and returning something in getValue(), but that doesn't work either.
Comment #3
kristiaanvandeneyndeThis sounds like a nice idea. Have you tried setting the value in hook_entity_load()?
Comment #4
joachim CreditAttribution: joachim commentedI haven't, but that felt a bit wrong in that we'd have to act on every single entity type and for every entity that's loaded, go check whether there's a Group Content plugin that's enabled for that entity type. That seems to me like it could really hurt performance.
Comment #5
kristiaanvandeneyndeWe can approach the field the way Group already does for the group_roles field on memberships, i.e.:
- define the field in config
- then apply that field where necessary
- in hook_entity_load check if the entity has a field called 'group'
- if so, check if the field is an instance of our field from config
- if so, load all groups for the entity (we have a helper function for that)
Comment #6
joachim CreditAttribution: joachim commentedThat's all doable with a computed field too.
It's just that I'm hoping there's a more efficient way of setting its value than hook_entity_load().
Comment #7
XanoYou do not want to use
hook_entity_load()
, as it will fail for any reference that is changed after loading the entity. A field with a computed property is probably the way to go. You could look into extendingEntityReferenceItem
with your own class, so to outside code your field looks like any other entity reference field (there is no interface that can be implemented, unfortunately). Instead of storing an internal entity ID, it loads the reference ID by getting another entity reference field's value. The name of this other (sibling) field can be part of your new field's settings, as well as the name of the second entity reference field on the dynamically loaded entity. By storing this in the settings, your two-step dynamic entity reference field will become reusable.Comment #8
joachim CreditAttribution: joachim commented> You could look into extending EntityReferenceItem with your own class, so to outside code your field looks like any other entity reference field (there is no interface that can be implemented, unfortunately).
I went some way down that route, but I couldn't figure out where to return the field's value within that class.
> Instead of storing an internal entity ID, it loads the reference ID by getting another entity reference field's value. The name of this other (sibling) field can be part of your new field's settings, as well as the name of the second entity reference field on the dynamically loaded entity. By storing this in the settings, your two-step dynamic entity reference field will become reusable.
In our case, the reference ID needs to be obtained by querying Group Content entities. I can see how this *could* be made reusable, but it would be more complicated than just storing the name of another field.
It goes like this:
- given a Node entity
- query for the GroupContent entity where:
- the type is derived from the Node's type
- the foo field is equal to the Node ID
- get a field value from the retrieved Group Content entity
So the settings would need to store the way of building the query. Or we hand over that logic to a plugin, and the settings store the plugin ID.
Comment #9
kristiaanvandeneyndeRight, I was thinking in D7 terms where a computed field would generally be set on entity or field load and then be kept up to date during runtime. If we can do this with an entity reference subclass, then that's fine too.
However, looking at https://www.drupal.org/node/2112677, it seems we may be able to pull it off by using
setClass('\Drupal\group\ComputedValue\ParentGroup')
or something.Comment #10
XanoI would recommend you set the following requirements for this new field:
EntityReferenceItem
class so formatters are able to work with it. There is no specific interface you can implement, so this requires a bit more thought to get right.hook_field_formatter_alter()
to mark your new field type as supported for every formatter that already supports entity reference items.Is this a reverse entity reference? In that case this would be hard to make reusable in the beginning. I agree that writing a use-case-specific solution is probably best to start with.
Comment #11
joachim CreditAttribution: joachim commented> Is this a reverse entity reference?
Hmm come to think of it, not really.
There are two real fields (which are base fields) on Group Content entity which point to the Group entity and the Node entity (or other entity that is a group member). The computed field on the Node should point to the Group.
We have:
and we want:
Comment #12
joachim CreditAttribution: joachim commented> by using setClass('\Drupal\group\ComputedValue\ParentGroup') or something.
I tried that, but that class expects to be the same sort of thing as EntityReferenceFieldItemList, and I couldn't find a way to get that to return a value.
> To the outside world, your field must look exactly like the EntityReferenceItem class so formatters are able to work with it.
I made a start on this approach. I don't see a way to change that class for the entity_ref field type, so I had to declare a new field type, which I don't think is ideal, as other modules won't know it's a reference field.
I've had to stop working on this for the time being, but here's a patch of my work branch. It's all a bit of a mess as I was trying various things, eg code from both the approaches above is still there, and also earlier work with pseudofields. But it can show what I've tried so far and perhaps be a starting point if someone else wants to look at this.
Comment #13
XanoA new field type is indeed the right way, and you are right about other code not knowing your new field type is compatible with the standard entity reference field. That is why formatter info must be altered to define that entity reference formatters work for the new field type as well.
Comment #14
joachim CreditAttribution: joachim commented> you are right about other code not knowing your new field type is compatible with the standard entity reference field
Isn't that going to rule out a lot of potential benefits? If this could use the existing entityreference field type, then any other module that does something with entityreference fields could work with this.
If it's not possible to make a computed entityreference field, should we be thinking of making a feature request on Core?
Comment #15
XanoYou can swap out the class of the existing entity reference plugin, but I'd recommend against that. Such practices should generally be limited to specific applications, and not be used by reusable extensions like Drupal modules. What if multiple modules start swapping out the same thing?
Comment #16
joachim CreditAttribution: joachim commentedAgreed, that's not viable for a contrib module.
What bugs me is this:
> //->setClass('\Drupal\group\TestEntRefFieldValue')
This is changing a class for the field, but the wrong one!
Comment #17
kristiaanvandeneyndeInside of an EntityReferenceFieldItemList, you can call getEntity() to get the entity the field belongs to. When you have that, you can get the parent Groups for that entity and set them as the value in getValue()?
I really think we should try doing this with plain old entity reference fields for the reasons joachim mentioned.
Comment #18
seanBJust ran into this. Link the core issue that could fix the computed property.
Comment #19
seanBJust posting some code that seems to work with #2392845-66: Add a trait to standardize handling of computed item lists. Hopefully this help someone. This is helping me index, filter and show groups related to content when using search api solr views.
I could create a patch if you would consider adding this?
And the class:
Comment #20
kristiaanvandeneyndeIf computed fields make it into core, I would definitely consider adding a backlink from groupable entities to their group.
Comment #21
realityloop@SeanB This is good for existing nodes, but throws errors when creating new nodes.
Offending code block:
Comment #22
seanBYeah, if
$this->getEntity()->id()
is empty we should probably bail out directly.Comment #23
adammaloneI've rolled the code in #19 along with recommendations from #22 into a patch for the group module. It seems to work fine at my end although would likely another review.
Comment #26
realityloopComment #27
mparker17The test failures in #26 occur because the test environment hasn't applied the patch in #2392845: Add a trait to standardize handling of computed item lists to Drupal core.
Comment #28
mparker17Updated the issue summary and hid older patches.
Since the module maintainer (@kristiaanvandeneynde) said in #20 that he wants to wait for #2392845: Add a trait to standardize handling of computed item lists to make it into core first, I've moved that issue to be a parent of this one, rather than simply a related issue, marking this issue as postponed, and updating the issue title accordingly.
If, for whatever reason, 2392845 does not make it into core, it may be wroth noting that the latest patch which does not depend on that patch is in #12.
Comment #29
mparker17Updated the issue summary problem/motivation and proposed resolution with more information.
Comment #30
mparker17Currently
GroupGroupReferenceItemList extends EntityReferenceFieldItemList implements FieldItemListComputedInterface
.But it looks like
FieldItemListComputedInterface
was removed in #2392845-86: Add a trait to standardize handling of computed item lists in favor of an abstract base class namedComputedFieldItemListBase
(see point #4 in @nuez's response) .Since multiple inheritance isn't a thing in PHP do you think it would work if we modified
GroupGroupReferenceItemList
toextend ComputedFieldItemListBase
and implementEntityReferenceFieldItemListInterface
(i.e.: the interface thatEntityReferenceFieldItemList
implements), copying over methods fromEntityReferenceFieldItemList
and its ancestors? Or should we look for a different solution?Comment #31
seanBI believe the patch in [#12219727] should not be necessary. In 8.4 there is an example of a computed field in
Drupal\content_moderation\Plugin\Field\ModerationStateFieldItemList
. This doesn't need the patch. The base class proposed in the patch would make it easier, but this does not have to be blocked on that.I guess this clears the path to add this in the module right now and just extend
EntityReferenceFieldItemList
.Something like this should work (don't have time to test it, but just changed some working code I had somewhere as an example):
Comment #32
seanBBack to needs work..
Comment #33
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedI just posted a patch in #2392845-105: Add a trait to standardize handling of computed item lists that will be very helpful if the Group module can add a dependency on Drupal 8.4.x. The code from #31 will be reduced to the implementation of the
computeValues()
method.Comment #34
recrit CreditAttribution: recrit commentedRolled #31 into a patch that can be used now without the need for Drupal\Core\Field\FieldItemListComputedInterface.
Comment #35
recrit CreditAttribution: recrit commentedThe attached #35 patch implements the isEmpty() method. I ran into the issue where search api would not index the field since it checks isEmpty() first.
Comment #36
kristiaanvandeneyndeI was following that issue amateescu, nice work there! We should definitely use that trait and up the version dependency to 8.4.x
Comment #37
recrit CreditAttribution: recrit commentedPatch updates:
* Set cardinality to unlimited. This should be unlimited since its a single to multiple relationship. Search API would incorrectly index the field as a single value causing errors during indexing.
* By default, hide the fields from the view display. This should be the default so that it does not pollute displays of existing sites. An admin can opt-in to show the fields.
Comment #38
seanBAwesome the computed trait from #2392845: Add a trait to standardize handling of computed item lists is in core now! Let's use that :)
Comment #39
jibranComment #40
geek-merlinOK, here we go! Patch flying in that
* leverages ComputedItemListTrait thus greatly simplifying the computed field
* enables the field's widget with a POC postSave() method that can trigger adding and deleting content/group relations. (for now it shows the selected IDs, tested)
Comment #41
kristiaanvandeneyndeNice, thanks for working on this!
You could perhaps load all GroupContentType entities and see which entity types are supported?
Also I'd like to see tests for any new functionality going in. Even if it's as simple as "yup, this node knows about the group it's in"
Comment #42
clemens.tolboomComment #43
modestmoes CreditAttribution: modestmoes commentedMade a patch working out how the postSave() from #40 could work
Comment #44
modestmoes CreditAttribution: modestmoes commentedComment #45
modestmoes CreditAttribution: modestmoes commentedTrying to re-roll this patch.
Made a patch working out how the postSave() from #40 could work
Comment #46
geek-merlinNice work! I did not test this but the code looks straightforward and well commented.
2 nits:
* I'd remove the _none option earlier in the code for more clarity.
* The code is not at all node specific so let's call it entity.
;-)
Comment #47
anruether#45 works for me!
Comment #48
zenimagine CreditAttribution: zenimagine commentedI applied the patch #45 and it works.
But I have some questions:
- Currently if I create a node, I have access to all groups. How to restrict to my own groups?
- The group field is not required. How to require the selection of a group?
- Currently the field allows to select several groups. How to limit it to a single group?
- In the TWIG of my type of node, I want to make the field group. What is the TWIG code to display the group in relation?
Thank you
Comment #49
zenimagine CreditAttribution: zenimagine commentedI succeeded with the following code :
{{ content.groups }}
But in the module "Message" I tested the following token and it does not work. There is no group field in the token.
[message:field_node_reference:entity:groups]
Comment #50
zenimagine CreditAttribution: zenimagine commentedIt would be nice to do like "Drupal Commerce".
Create a true lock field for groups.
Comment #51
anruetherJust to inform those who worked on the patch in this issue: There is ongoing work on another patch with similar functionality in #2813405: Adding Content Relationships Outside of Groups.
From what I understand with a different approach and a bit different functionality.
Comment #52
geek-merlinI have looked into all 3 dup issues and propose to move some of this code to #2813405-46: Add a field to view and edit content's groups - see my comment there.
Comment #53
jidrone CreditAttribution: jidrone at Mobomo for Vibrent Health commentedHi everyone,
I also propose to close this as duplicated in favor of #2813405: Add a field to view and edit content's groups, that one now have the computed field approach and provides a more complete solution.
Comment #54
anruetherLet's do it.
Comment #55
scuba_flyI know this is closed duplicate, but I just noticed this in the patch.
:wq
Comment #56
Henry Tran CreditAttribution: Henry Tran at Deloitte Digital commentedI've rerolled #45 to 8.x-1.x
Comment #57
Henry Tran CreditAttribution: Henry Tran at Deloitte Digital commentedSorry #65 does not work correctly, I've re uploaded.
Thanks
Comment #58
clemens.tolboom@tvhung this issue was closed as a duplicate of #2813405: Add a field to view and edit content's groups so your patch will not be reviewed.
Comment #59
Henry Tran CreditAttribution: Henry Tran at Deloitte Digital commentedI've rerolled to drupal 9 compatibly.
Comment #60
hitesh-jain CreditAttribution: hitesh-jain commentedFixed issue for empty computed field value.
Added below condition to GroupGroupReferenceItemList -> postSave method
Comment #61
hitesh-jain CreditAttribution: hitesh-jain commentedFix patch number.
Comment #62
lexhoukExtend patch from #59 by adding a possibility to support different entity types.
Comment #63
anruether@chmez and @hitesh-jain please note that most people won't see this anymore, because this issue is closed. The most recent (and robust) approach is worked on in a dedicated module now: https://www.drupal.org/project/entitygroupfield It would be great to join forces over there.
Comment #64
lexhouk@anruether thanks for the info. The last patch was created just like a workaround for Open Social but in future, we definitely should switch to a solution from a related issue or the suggested module.
Comment #65
lexhoukDefine content plugin based on the entity type.