Problem/Motivation
There are potential use-cases for allowing the flagging of config entities.
In the message_subscribe module, flags are used to denote subscriptions:
- Subscribe to comments for a node is handled by flagging the individual node
- Subscribe to all content for a given user or term is handled by flagging the user or term
- Subscribe to all content of a given type would be handled by flagging the node type
This screenshot from the original IS isn't from message_subscribe, but indicates the same use case:

where announcements and discussions are flagged node types.
Proposed resolution
Utilize the Dynamic Entity Reference module for the flagging entity's reference column (now a single flagged_entity base field.)
$fields['flagged_entity'] = BaseFieldDefinition::create('dynamic_entity_reference')
->setLabel(t('Flagged entity'))
->setDescription(t('The entity that has been flagged.'))
->setCardinality(1)
->setRequired(TRUE);
This replaces the previous 3 base fields on the flagging entity (entity_type, entity_id, and the computed flagged_entity).
Remaining tasks
User interface changes
API changes
Data model changes
Comments
Comment #2
chx commentedComment #3
berdirFor example because flag can't store non-numeric entity ID's. So you can add flags, but it will fail to actually flag entities.
Comment #4
chx commentedI see a string.
Comment #5
chx commentedNow at least creating node_type flags work even if the counter will fail.
Comment #6
socketwench commentedFlag 8 did support flagging config entities at one time. We never removed the ability within the fields, only added a block in EntityFlagTypeDeriver.
I believe it was Joachim that suggested we remove support for config entities.
Comment #7
joachim commentedA first problem is that Dynamic Entity Reference appears to only allow referencing content entities, and that's something we might be moving towards using (in fact, chx suggested it on an issue recently I think).
Comment #8
chx commentedBut now we have all the code not to need DER: we have an entity reference field on our own and using DER would only allow you to rip out the 15 or so lines of code I added recently and not much more. And, mind you, some of that code is about disallowing moving a flagging to a different entity. And based on the parent issue and this issue people actually need to flag config entities and we almost have the code to do it so ... why not?
Comment #9
socketwench commentedUpping this to major since I want this resolved before beta releases.
Comment #10
joachim commented> But now we have all the code not to need DER: we have an entity reference field on our own and using DER would only allow you to rip out the 15 or so lines of code I added recently and not much more.
Would DER not provide some of the Views support for us?
Comment #11
chx commentedWell, you already have an entity reference field, it's computed but nonetheless, it's there. If you want views integration then you just need to break backwards compatibility, drop entity_type, entity_id from the database and store flagged_entity instead (and write an update hook moving the data over) and then core provides you with views integration. Where do you see the need for DER?
Edit: or just eat the duplication and store all three of entity_id, entity_type and flagged_entity .
Comment #12
berdirAn entity_reference stores just ID's, for a single type. And the schema that it generates is for a single entity type. What comment.module does is a) cheating and b) doesn't support config entities either.
DER offers an entity_type/entity_id reference as a generic pattern. However, it currently actually only supports content entities too, so it wouldn't help us here.
Comment #13
chx commentedIf we want to store the flagged entity reference then we found an entity API missing feature: fields per bundle can't have differing schema.
So you want DER because you have the
{flagging}table and different rows might differ to different entity types which ER doesn't support and because DER would give you Views integration.We could keep the current data structure and provide Views support ourselves, per flag we can write up the correct JOIN. I'd prefer this direction but I understand it's a bit of a work to write / maintain. Also, since the entity_id needs to be string, if you are on MySQL <5.7 then you can't index on the casted value and might have a bit of a performance problem.
Now, all of these weak, compromising solutions make me wonder whether having one Drupal field / database column per flag would be useful. Solves all the problems immediately, right? We just have a bunch of ER fields, Views support flows from core. We can use tidy mechanics to make this a database storage internals and people using the entity would never need to know, they can just use
$flagging->flagged_entity. We could easily define one field per bundle in bundleFieldDefinitions and we could copy the right value on set just as the current code does now. How crazy is that?Comment #14
jibranComing from #2555027-13: Support non-numeric entity ID's quoting myself here.
This seems viable given that we might end up doing it in #2723703: Add relationship to flagged entities when Flagging is base table anyway.
Re: @joachim from #2657384-10: Flagging should use some standard entity reference
As per DER status report the module is stable for quiet a while now. There are only two pending issues left in #2447963: [meta] DER roadmap for 8.x-1.x. I'm planning to fix them by the end of this month so that DER can have a stable release.
As far as moving it to core is concerned #2407587: Allow multiple target entity types in the entity reference field we need a product manager approval afaik no one is working on that.
imo #2555027: Support non-numeric entity ID's is a new feature and it can get in anytime we want without any disruption to stable release. The follow up of #2555027 would be to add views integration. Given that DER already support int entity id that would not be a huge task.
Comment #15
chx commentedRerolled against HEAD.
Comment #16
socketwench commentedComment #17
socketwench commentedStill needs tests against config entities
Comment #18
chx commentedThe whole issue is a gigantic mess there's no way out of this but DER 8.x-2.x
See,
$fields['entity_id'] = BaseFieldDefinition::create('string')you can't join on this. You do need a string because Drupal core supports content IDs with string IDs seeDrupal\entity_test\Entity\EntityTestStringIdbut at the same time a string is not good because you can't join to nodes, users and such.I solved this conundrum neat and proper in DER 8.x-2.x and I strongly recommend flag to update to use it despite it's not released yet but it's only UI problems that keeps us from releasing it.
Of course we can put this off and just have a config entity tested here but at the same time if we go DER anyways which is not avoidable then why bother?
Comment #19
jhedstromThis is a rebase of #15, I'm going to work on some tests.
The idea of flagging config entities is of use over here in message_subscribe as a way to subscribe to, for instance, all content of a given type.
Comment #20
jhedstromHere's a very basic test. It caught a needed schema change to
flag_counts.One question I had: should this behavior be configurable, defaulting to false, so the UI isn't cluttered with config entities for the simple use cases?
Comment #21
jhedstromThe above patch contains similar changes to #2546074: Update flag counts table schema, but that issue will need to be committed before this one, and then those duplicate changes removed here.
Comment #22
socketwench commentedSo what's the call, then? The proper solution sounds like using DER, but the most recent patch doesn't use it.
Comment #23
chx commentedSomeone needs to make that call. All I can give is information. The issue summary of #2555027: Support non-numeric entity ID's is very relevant.
Comment #24
jhedstromIt seems like if changing to a string isn't enough, then this issue should require DER and go from there?
Comment #25
joachim commented> DER 8.x-2.x
DER (https://www.drupal.org/project/dynamic_entity_reference) has a RC on the 1.x branch; the 2.x branch is in dev.
Needs a summary update to explain the situation clearly.
Comment #26
jibranDER 2.x branch is in alpha state for quite a while now but I don't want to make a release until #2766175: Fix the Views integration for entities with string ids. and #2808337: Make use of proposed entity table relationship refactor are fixed. And once #2766187: Allow config entity references is fixed we'll release the beta.
Comment #27
socketwench commentedMoving to postponed given #26.
Comment #28
jhedstromRemoving the postponed status, as the remaining issues for DER need not block this. I'll start working on a patch that utilizes DER.
Comment #29
jhedstromComment #30
jhedstromThis will fail on the testbot, because new module dependencies are not processed for patches. All tests are green locally. Posting this sooner rather than later to get some feedback.
Comment #33
jhedstromStill at NR.
Comment #34
jibranI'm really glad to see the practical use of DER.
This should be
dynamic_entity_reference:dynamic_entity_reference (2.x). As per https://www.drupal.org/node/2000204 and https://www.drupal.org/node/542202#dependenciesJust make sure the condition is between same type of columns. There is
\Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem::entityHasIntegerId()function in #2766175: Fix the Views integration for entities with string ids. you can use.Comment #35
jhedstromThis sets the proper version for DER. I'll fix the remainder of #34 once #2766175: Fix the Views integration for entities with string ids. has been committed, since it has the method needed to check int vs string.
Comment #36
jhedstromHmm, that change might not work until there is an official release of DER?
Note message_subscribe depends on flag:
Comment #37
jibranI moved
\Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem::entityHasIntegerIdto 8.x-2.x in https://www.drupal.org/commitlog/commit/65971/de0b1d85476037ed669bea835a...Comment #38
jhedstromThis attempts to take into account the switching target id column. However, note the
@todos. I could not get the_intcolumn to work with EFQ at all. Is that a known issue?This is the exception:
Drupal\Core\Entity\Query\QueryException: 'flagged_entity__target_id_int' not foundI also rolled this patch utilizing the new method added over in #2827219: Add helper method to retrieve complete column name, but can reroll if it is determined that helper method won't go in.
Comment #39
jibran#2808337: Make use of proposed entity table relationship refactor will fix that.
I'll have a look at #2827219: Add helper method to retrieve complete column name later today.
Comment #40
jhedstromRe-roll to utilize the latest helper method in #2827219: Add helper method to retrieve complete column name. Note that #2808337: Make use of proposed entity table relationship refactor, which is test-only, has not resolved the issue in #38. When the query builder looks for column mappings in
Tables::ensureEntityTable(), the_intcolumn is not listed as one of the table mappings:as such, the
@todos are still in this patch.One question, shouldn't DER, in the case of an EFQ, take care of the string/int column logic already? In which case these
@todos could simply be removed...Comment #41
jhedstromThis is postponed on #2808337: Make use of proposed entity table relationship refactor. In #40 I hadn't realized there was more in that issue than just the test.
Comment #42
jibranLet's fix #2808337: Make use of proposed entity table relationship refactor and after that we can create an alpha tag for DER.
Comment #43
joachim commentedThis would require handling of the 'show as field' and 'show on form' options.
Also, could someone explain the use case? I don't understand how the screenshot is showing a use of Flag.
Comment #44
jibranI created 8.x-2.0-alpha1.
Comment #45
jhedstromI'm approaching this issue from a very similar spot to that screenshot. In the
message_subscribemodule, Flag is used for users to subscribe or unsubscribe from things. For subscribing to comments on a node, the node entity gets flagged. For subscribing to all content of a given term or user, the term or user is flagged.The big missing piece there is subscribing to all content of a *content type*. The most elegant solution to that would be to flag the particular content type.
I've updated the IS accordingly.
Comment #46
jhedstromHere's a reroll now that #2801423: FlaggingStorage does not update cached Flagging status. and #2808337: Make use of proposed entity table relationship refactor are in. The
@todosare removed because DER now determines which field to use for EFQs.Comment #49
jhedstromDue to the way the drupal testbots work, adding a new module dependency via a patch does not download that for the tests. Only once the
.info.ymlfile is committed are new dependencies registered, so until then, these tests won't pass on the testbot. They are all green locally.Unavailable module: 'dynamic_entity_reference'Comment #50
jhedstromHere's a reroll against the latest 8.x-4.x. As mentioned above, tests for this will not pass on the test bot until DER is committed as a dependency, but I have re-verified this is passing locally for all tests.
Comment #52
jibranWe can create a feature branch now to run the tests on d.o.
Comment #53
jhedstromGreat idea! Let's do that.
Comment #54
joachim commentedAFAICT this used to keep the computed field up to date. What does it do now? Also, 'entity_id' is no longer a base field, is it?
Comment #55
jhedstromre #54 hmm, excellent question. I'm guessing it can be removed since DER would take care of computing/gathering the entity?
Comment #56
martin107 commentedI am happy with the idea behind this issue.
I have a kink to report, which is only visible if you first have NOT downloaded dynamic_entity_reference
It looks like the dependencies are not setup correctly,
here is the output from "drush en flag" with the patch applied.
Comment #57
jhedstromWe won't be able to address #56 here--that's an issue with Drush preferring stable releases/and also not parsing the version requirements out of
.info.ymlfiles. The error output there should be sufficient to guide people towards the correct version of DER though.Comment #58
joachim commentedThe matter of how people with existing sites are going to update their data came up at #2845567: make use of ContentEntityBase::baseFieldDefinitions(); make flag_id an entity reference field...
I'm minded to say if this issue gets in 4.x (as opposed to future 5.x), so does that one, as two painful field changes isn't that much worse than one...
Comment #59
jhedstromThis should address the
onChangemethod. We also no longer needed the constructor method, so that is removed.Comment #61
jhedstromThis is at NR since tests won't pass on the testbot until we commit (or commit to a feature branch).
Comment #62
socketwench commentedCan we try that?
Comment #63
jibranYes, you can. Only, the maintainers can do that. You have to create a branch
2678756-allow-config-entitiesand commit this patch and push it to d.o.Comment #65
socketwench commented*Finally* got around to committing that to a feature branch. I hope I did it right?
Comment #66
jibranYeah, it is correct I think there is a bug in composer workflow on testbot.
Comment #67
jhedstrom@jibran where did you see the test results for this branch?
Comment #68
jibranhttps://www.drupal.org/pift-ci-job/592232
Comment #69
jhedstromI spoke with @Mixologic, and these are known failures (feature branches cannot currently be tested). I've rerun all these tests locally and they are still green.
Also, even though Flag is in alpha, I've added an update hook:
we could add this to the patch, or just direct folks to this comment who need the update hook.
Comment #70
jhedstromAnd the same update hook in patch form.
Comment #71
jhedstromAny thoughts on how to move forward with this?
Comment #72
jibran@jhedstrom let's create a PR on github so that we can run tests.
Comment #75
jibranMaybe this will work.
Comment #76
joachim commentedSmall bug in the update code:
That's not the integer column that the code is adding.
And this is probably a problem in DER rather than here, but EntityTypeInterface::BUNDLE_MAX_LENGTH is for bundle names, not entity type names.
Comment #77
jibranPlease have a look at http://cgit.drupalcode.org/drupal/tree/core/lib/Drupal/Core/Field/Plugin....
flagged_entity__target_idis a string column and the new cloumn would beflagged_entity__target_id_intso I don't think there is anything wrong with the update code.Do we want to add update path as well? If yes then let's do that in follow-up with proper tests.
Let's create a local variable.
I think this should be
$keys['indexes'].I'd like this to be in a separate update hook but DER is doing the same thing so I think this is correct because
create_columnservice is doing the proper exception handling.DER is doing
update($table)->fields([$int_column => 0])->execute()instead\Drupal::keyValue('entity.storage_schema.sql');should also be updated see der.install:99 for more details.@jhedstrom do you think, we can do something similar to #69 for #2823528: Allow conversion of ER fields to DER fields as well?
Comment #78
jhedstromAgreed we should add the update hook in a follow-up (or not at all since we haven't been previously doing update hooks while in alpha).
@jibran I think the approach in #69 could be done in a more generalized manner to address #2823528: Allow conversion of ER fields to DER fields. It definitely works as a one-off as I have manually tested it on a site with flagging data.
Comment #79
joachim commented> flagged_entity__target_id is a string column and the new cloumn would be flagged_entity__target_id_int so I don't think there is anything wrong with the update code.
Yes, but the code and the comment don't agree!
Comment says 'integer column', but the code is adding the string column.
> Do we want to add update path as well? If yes then let's do that in follow-up with proper tests.
Nope, we're still not at stable release yet. I've said before we should collect update code on a single support issue, so that people who are using Flag in production (despite the warnings on the project page!) can use it & contribute.
Comment #80
jhedstromIt's a bit confusing, but that method is creating the int column. Its argument is the non-int target_id column name. From
IntColumnHandlerInterface:This is a fantastic idea!
Comment #81
jhedstromI've added #2858553: Pre-beta update hook code. What else needs to be done here?
Comment #82
jibranNothing if you are asking me.
Comment #83
joachim commented... just that DER needs a stable release.
Also, would be good if the issue summary could mention the resolution to use DER, with a link to the project.
Comment #84
jibranAs I said in #26 it is almost in beta state. I can release RC and as soon as the current queue is cleared I'll release the stable version. After RC there would be no API change and DER will support the upgrade path.
Comment #85
jibranWould you agree on using DERv2 rc for flag alpha and beta release phase?
Comment #86
joachim commentedGiven how far Flag is from RC itself, and that DER seems to be advancing faster than us, yup, RC is fine.
Comment #87
jhedstromIt seems this need not wait for a DER RC since Flag is still in alpha? Should something big change in DER, we could keep this code base in sync as needed...
Comment #88
jhedstromAdded the requested info to the IS.
Comment #89
jonathanshawShouldn't this still be Needs Work for #77.2?
Comment #90
jhedstrom@jonathanshaw that was feedback regarding the upgrade path, which isn't part of this patch, but is over in #2858553: Pre-beta update hook code now.
I'd like to see this committed so that various contrib modules requiring flag can start to rely on this functionality... as mentioned in #87, since both DER and Flag are still in alpha, if something in DER changes, that change can quickly be incorporated here too...
Comment #91
socketwench commentedReminder to self, this patch is waiting on DER 2.x to get to the RC stage.
https://www.drupal.org/project/dynamic_entity_reference/releases
Comment #92
jibranLet's fix #2867102: Incompatibility with jsonapi and come up with the plan for #2835542: Utilize service decorator instead of taking over entire EFQ service in a way that we can make the changes without BC break(or won't fix the issue) then I'm happy to release DER RC.
Comment #93
jhedstromComment #94
MerryHamster commentedI have faced with the error from issue https://www.drupal.org/project/flag/issues/2864440
And patch #75 helped me.
But there is Flag 4.0.0-alpha3 version module on the project so I recreated patch for this version.
Maybe it will useful for somebody.
Comment #95
kevin.dutra commentedMinor cleanup from that re-roll
Comment #96
martin107 commentedThis is just a trivial correction -- but in other news it looks like our random test failure is raising its ugly head.
The general trend in core is to migrate away from array() to [].
I am just reversing a movement in the other sense - and maintaining the use of [].
Comment #97
berdirI've been ignoring this because I'm not sure what to do with it. It's definitely not a beta blocker, because beta is out and this adds a lot of complexity.
At least it will need an upgrade path, which is going to be a challenge.
Comment #98
xdong commentedComment #101
zspratt commentedI have made a commit to the issue fork in branch 8.x-4.x, which applies patch #98 2678756-97.patch by xdong and patch #70 2678756-update-hook-do-not-test.patch by jhedstrom, implementing support for flagging config entities. I have tested this on a local WAMP installation of Drupal 9.4.2 running on PHP 8.0.13-nts via fastCGI, and everything seems to be working as expected. I can flag both content and config entities as normal, and all the data stored in the flagging and flag_counts tables looks good.
A merge request has been created for my commit, maintainers would you be able to have a look at this and review it?
Comment #102
akoepke commentedComment #103
akoepke commentedCan we have this functionality looked at again?
We are in the process of migrating from Drupal 7 to Drupal 9 and have a Flag attached to a bundle so users can subscribe to notifications for new content.
In Drupal 9, this entity is now a config entity which means we can't migrate the Flag unless support for this is added.
Comment #104
kevin.dutra commentedRe-roll of the patch from #98 for 4.0-beta4.
Comment #105
kevin.dutra commentedOops, minor goof in the re-roll.
Comment #106
kevin.dutra commentedAnd it looks like some additional tweaks are necessary if you're using DER 3.x.
Comment #107
kevin.dutra commentedLooks like I missed something for the DER 3.x version.
Comment #108
ivnishNeeds rebase
Comment #109
ivnishComment #111
deaom commentedJust to add a little clarification: phpunit run with MySql fail, because of the table prefix which is test, this is then considered as a system table which then triggers the error. Updated the gitlab-ci so it runs mysql and pgsql in parallel as pgsql does not have the test issue/limitation. As seen from that, tests are failing so this is not ready to be merged and needs some additional work.
Comment #112
deaom commentedThe tests that are failing for pgsql are in relation to the views and the relationship comparison "operator does not exist: character varying = bigint" and "invalid input syntax for type bigint". There is a patch for core that should solve this issue so not something that needs to be handled in Flag: #3079534: Views JOIN condition fails in PostgreSQL when comparing entity identifiers of different datatypes. And there is also an issue opened in flag: #2864440: PostgreSQL problems on entity_id of type varchar with flagging and flag_count tables in regards to that.
With MySql DB locally all the tests are passing. On Drupal CI the issue with MySql is with the naming of the DB tables with the test prefix, which then makes them a system table and triggers can't be triggered on system tables. Tried to rename the tables with no luck.
Leaving the status to needs work just because of the tests issues, but would be good if somebody could test manually and confirm if everything works as expected. And then maintainers can decide on how to proceed.
Comment #113
berdirThe system table thing isn't the table name but the database, see #3463044: Do not use the system "mysql" database to install Drupal.
Comment #114
deaom commentedThis needs to be corrected in the gitlab-ci templates as when changing the db the db is then not found
PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000] [1049] Unknown database 'drupalci_db' in /builds/issue/flag-2678756/web/core/modules/mysql/src/Driver/Database/mysql/Connection.php:142. Not sure if creating the DB would help solve the issue.Will revert the changes made to gitlab-ci.yml file.
The changes can be tested manually, this is now just an issue with the gitlab-ci testing.