Suggestion for SQLFilter with Inheritance #6120

Closed
opened 2026-01-22 15:27:06 +01:00 by admin · 6 comments
Owner

Originally created by @renanBritz on GitHub (Dec 6, 2018).

Originally assigned to: @Ocramius on GitHub.

Hello!

I know this is a topic that has been discussed before and repeatedly refused by the community (See #2924, #6329, #3364). But I have a suggestion that might fit the doctrine design, maybe:

Well, I agree that inheritance could cause concerns, especially because of DQL, which is statically typed and won't allow you to access child attributes in some cases. But that's besides the point...

What I suggest is: Pass the Root Entity Metadata to the filter, just as it was done so far, but also add a third parameter to the SQLFilter with the namespace of the child class. That could help us a lot in cases where we need to disable filters temporarially for a specific child class, or apply special logic to the filters.

Regards!

Originally created by @renanBritz on GitHub (Dec 6, 2018). Originally assigned to: @Ocramius on GitHub. Hello! I know this is a topic that has been discussed before and repeatedly refused by the community (See #2924, #6329, #3364). But I have a suggestion that might fit the doctrine design, maybe: Well, I agree that inheritance could cause concerns, especially because of DQL, which is statically typed and won't allow you to access child attributes in some cases. But that's besides the point... What I suggest is: Pass the Root Entity Metadata to the filter, just as it was done so far, but also add a third parameter to the SQLFilter with the namespace of the child class. That could help us a lot in cases where we need to disable filters temporarially for a specific child class, or apply special logic to the filters. Regards!
admin added the New FeatureWon't FixInvalid labels 2026-01-22 15:27:06 +01:00
admin closed this issue 2026-01-22 15:27:06 +01:00
Author
Owner

@Ocramius commented on GitHub (Dec 6, 2018):

A filter is to be applied to a specific level of the inheritance: when you filter at root level, that is (by design) all the context you have, since child classes don't effectively exist.

Since type information is known at metadata setup time, configure one filter per child class then.

This is also related to one of our oldest invalid issues, DDC-16: https://github.com/doctrine/doctrine2/issues/2237

@Ocramius commented on GitHub (Dec 6, 2018): A filter is to be applied to a specific level of the inheritance: when you filter at root level, that is (**by design**) all the context you have, since child classes don't effectively exist. Since type information is known at metadata setup time, configure one filter per child class then. This is also related to one of our oldest invalid issues, DDC-16: https://github.com/doctrine/doctrine2/issues/2237
Author
Owner

@andrews05 commented on GitHub (Sep 16, 2019):

@Ocramius, I'm new to Doctrine and still trying to learn it all. Can you explain what you mean about configuring filters per child class? My understanding of filters is they are added at the config level and enabled at the entity manager level, with no particular connection to entity (or repository) classes.
What are my options for filtering a joined subclass?

@andrews05 commented on GitHub (Sep 16, 2019): @Ocramius, I'm new to Doctrine and still trying to learn it all. Can you explain what you mean about configuring filters per child class? My understanding of filters is they are added at the config level and enabled at the entity manager level, with no particular connection to entity (or repository) classes. What are my options for filtering a joined subclass?
Author
Owner

@metasearch7 commented on GitHub (Dec 23, 2019):

I join the question, What are my options for filtering a joined subclass?

@metasearch7 commented on GitHub (Dec 23, 2019): I join the question, What are my options for filtering a joined subclass?
Author
Owner

@andrews05 commented on GitHub (Dec 23, 2019):

@metasearch7 This is a horrible hack and I'm not recommending it but it is an option. I haven't run into any issues with it yet, but use at your own risk. For Doctrine v3, may need changes for v2.x.

public function addFilterConstraint(ClassMetaData $targetEntity, $targetTableAlias) {
    // Get the caller
    $caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS|DEBUG_BACKTRACE_PROVIDE_OBJECT, 2)[1]['object'];
    if ($caller instanceof SqlWalker) {
        // Access the private tableAliasMap
        $map = ((array)$caller)["\0".SqlWalker::class."\0tableAliasMap"];
        $map = array_flip($map);
        // Get the DQL alias matching the targetTableAlias (values are in the form "TableName@[dqlAlias]")
        $dqlAlias = substr($map[$targetTableAlias], strpos($map[$targetTableAlias], '@')+2, -1);
        // Find other entries for the same DQL alias
        unset($map[$targetTableAlias]);
        $childTables = preg_grep("/@\[$dqlAlias\]$/", $map);
    } else if ($caller instanceof BasicEntityPersister) {
        // Access the protected currentPersisterContext->sqlTableAliases
        $map = ((array)$caller)["\0*\0currentPersisterContext"]->sqlTableAliases;
        $childTables = array_flip($map);
        unset($childTables[$targetTableAlias]);
    }

    foreach ($childTables as $alias=>$ignored) {
        // Do stuff with alias
    }
}
@andrews05 commented on GitHub (Dec 23, 2019): @metasearch7 This is a horrible hack and I'm not recommending it but it is an option. I haven't run into any issues with it yet, but use at your own risk. For Doctrine v3, may need changes for v2.x. ```PHP public function addFilterConstraint(ClassMetaData $targetEntity, $targetTableAlias) { // Get the caller $caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS|DEBUG_BACKTRACE_PROVIDE_OBJECT, 2)[1]['object']; if ($caller instanceof SqlWalker) { // Access the private tableAliasMap $map = ((array)$caller)["\0".SqlWalker::class."\0tableAliasMap"]; $map = array_flip($map); // Get the DQL alias matching the targetTableAlias (values are in the form "TableName@[dqlAlias]") $dqlAlias = substr($map[$targetTableAlias], strpos($map[$targetTableAlias], '@')+2, -1); // Find other entries for the same DQL alias unset($map[$targetTableAlias]); $childTables = preg_grep("/@\[$dqlAlias\]$/", $map); } else if ($caller instanceof BasicEntityPersister) { // Access the protected currentPersisterContext->sqlTableAliases $map = ((array)$caller)["\0*\0currentPersisterContext"]->sqlTableAliases; $childTables = array_flip($map); unset($childTables[$targetTableAlias]); } foreach ($childTables as $alias=>$ignored) { // Do stuff with alias } } ```
Author
Owner

@metasearch7 commented on GitHub (Dec 24, 2019):

andrews05, yes, this is a fierce hack! I will try to avoid such decisions. Thanks nonetheless for your reply.

@metasearch7 commented on GitHub (Dec 24, 2019): andrews05, yes, this is a fierce hack! I will try to avoid such decisions. Thanks nonetheless for your reply.
Author
Owner

@NikitaKharkov commented on GitHub (Jul 10, 2020):

As a solution for this case, I propose to override all the find methods and add There necessary filtering. Sure, you always need to remember in all other queries you should add this filter(s), but it's better than nothing.

@NikitaKharkov commented on GitHub (Jul 10, 2020): As a solution for this case, I propose to override all the **find** methods and add There necessary filtering. Sure, you always need to remember in all other queries you should add this filter(s), but it's better than nothing.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6120