Orm: Suggestion for SQLFilter with Inheritance

Created on 6 Dec 2018  路  6Comments  路  Source: doctrine/orm

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!

Invalid New Feature Won't Fix

Most helpful comment

@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?

All 6 comments

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, 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?

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

@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, yes, this is a fierce hack! I will try to avoid such decisions. Thanks nonetheless for your reply.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexander-schranz picture alexander-schranz  路  3Comments

strayobject picture strayobject  路  4Comments

doctrinebot picture doctrinebot  路  3Comments

neomerx picture neomerx  路  4Comments

doctrinebot picture doctrinebot  路  4Comments