-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to define custom functions with callback instead of class name #991
Ability to define custom functions with callback instead of class name #991
Conversation
Hello, thank you for creating this pull request. I have automatically opened an issue http://www.doctrine-project.org/jira/browse/DDC-3054 We use Jira to track the state of pull requests and the versions they got |
@@ -3353,7 +3353,12 @@ public function CustomFunctionsReturningNumerics() | |||
$funcName = strtolower($this->lexer->lookahead['value']); | |||
$funcClass = $this->em->getConfiguration()->getCustomNumericFunction($funcName); | |||
|
|||
$function = new $funcClass($funcName); | |||
if ($funcClass instanceof \Closure) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about
if (is_string($functName)) {
$function = new $funcClass($funcName);
} else {
$function = $funcClass($funcName);
}
Also, I'd change the naming from $funcClass
to $functionName
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$function = is_string($functionName)
? new $functionClass($functionName)
: $functionClass($functionName);
@mnapoli what is the use case for having a function coming from a container? |
@Ocramius Regarding the use case, I have one with https://github.com/mnapoli/DoctrineTranslated: SELECT e FROM MyEntity e WHERE TR(e.name) = 'hello' Here SELECT e FROM MyEntity e WHERE e.name.en = 'hello' (when the locale is Have a look here: https://github.com/mnapoli/DoctrineTranslated/blob/master/src/Doctrine/TranslatedFunction.php The test is here: https://github.com/mnapoli/DoctrineTranslated/blob/master/tests/DoctrineTest.php The current locale must come from somewhere outside the DQL function. I don't want to get into too much details but basically the TR function will get the current locale (and the fallbacks) from the TranslationManager, which is a service. But managing how objects are created, not just for custom functions, is a problem I regularly have. I know you have already told me (mailing list) "these should be very simple classes without dependencies" but I disagree, I have been limited by this so many times and given it can be fixed quite easily I would love to see this fixed. |
@mnapoli I get what you are trying to do, I'm just not sure if it is a good idea... Not really convinced. On the other side, this is indeed ok as the constructor arguments for a function are not constrained by an interface (nor will). |
I don't see a reason to put this kind of restriction. I would consider it bad practice in any library to create objects directly (I mean for extension points: objects provided by end-users) without providing an alternative. |
That makes a whole lot of sense :) |
Code updated with the remarks. Anyone wants to give feedback too? I'd love to get this going, I really need it for DoctrineTranslated. |
Ability to define custom functions with callback instead of class name
\o/ thanks! |
|
||
$function = is_string($functionClass) | ||
? new $functionClass($functionName) | ||
: $functionClass($functionName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mnapoli could you change it to call_user_func($functionClass, $functionName)
to support non-closure callables on PHP 5.3 too ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(fixed in #1031)
…entation Documentation for #991
Right now the only way to define custom DQL functions is by giving the class name, and Doctrine will create the class:
This is very limiting when the custom functions has dependencies, for example it can't be created by a DI container.
The approach I have taken here is very simple: it allows to define a callback instead of the class name: the callback will be called and it should return the instance:
On a side note, I think it would be great to generalize that approach because currently there are a lot of places where the same constraints apply.