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.
When using options.module I was trying to set allowed_values_function to a static method, in php 5.5 and 5.6 this is not possible, switching to call_user_func_array()
this would be possible, also it's a lot cleaner (and doesn't throw warnings in my PHPStorm).
Comment | File | Size | Author |
---|---|---|---|
#33 | 2678014-33.patch | 5.49 KB | pk188 |
#30 | increment-2678014-29.txt | 4.2 KB | pwolanin |
#30 | 2678014-29.patch | 5.44 KB | pwolanin |
#22 | allowed_values_function-2678014-21.patch | 1.24 KB | arunkumark |
#17 | handle-2678014-17.patch | 1.24 KB | timmillwood |
Comments
Comment #2
dawehnerJust curious, should we have a is_callable in the if statement?
Comment #3
timmillwoodI'm up for that.
Comment #4
dawehnerOh passing a parameter by reference is still a thing?
Comment #5
timmillwoodI guess so because if I don't pass it by reference I get the following error:
Comment #6
tstoecklerThis is just me, but I disagree with the is_callable. You can only ever set allowed_values_function from code, so even if it ends up in code, there's really no user interaction that could cause a failure. So if the allowed_values_function is not a callable it's either a straight up developer error (typo, ...) or it's a problem with the setup (borked autoloader, module not installed, ...). In both cases I'd rather have a fatal, than use a potentially bogus default value, so I can actually fix the problem.
Leaving at needs review to get more opinions on this.
Comment #7
timmillwoodGood points @tstoeckler, so either patch is open for RTBC ;)
Comment #8
dawehnerI agree, well ideally we would check it and otherwise throw an exception, but I agree, there is no much difference to a call to undefined function.
Comment #9
tstoecklerI would totally dig that, but yeah, not sure whether the twisted joy that I feel when I see typed exceptions bubble up to my browser is worth coding and maintaining those extra LOCs.
Comment #10
dawehnerWhy not, its just 3 lines.
Comment #11
timmillwoodHow about this?
Comment #12
dawehnerAre we sure
$function
can be cast to a string?Comment #13
timmillwoodhrm... good point!
Tested this by setting
This throws
Comment #14
dawehnerOOOHHH
I didn't knew
is_callable()
has this functionality!Comment #15
timmillwoodJust wondering if we should extend the scope of this patch by catching the exception in
\Drupal\options\Plugin\Field\FieldType\ListItemBase::getSettableOptions
and\Drupal\options\Plugin\Field\FieldType\ListItemBase::generateSampleValue
.Not sure if it's best to throw it uncaught, or to catch it, but will leave the option out there with this patch.
Comment #16
deviantintegral CreditAttribution: deviantintegral at Lullabot commentedThis patch has the nice side effect of clearing up a PHPStorm error that the entire file is invalid due to the setting method returning mixed and not a callable.
Code style, we need this blank line and the one between @return and @throws.
Should we throw http://php.net/manual/en/class.badfunctioncallexception.php or http://php.net/manual/en/class.badmethodcallexception.php instead?
This I think highlights why we should throw an exception above. Let's say the callback throws it's own exception, it's going to be silently logged instead of giving any other code a chance to deal with it.
I would say we should either catch a specific exception (possibly even subclassing one of the above) or remove the catches entirely.
Comment #17
timmillwoodI think we should remove the catches too, so working from patch in #13.
Updated the docblock, and throwing BadFunctionCallException now, that seemed appropriate seeing as this is allowed_values_function, and not allowed_values_method.
Comment #18
deviantintegral CreditAttribution: deviantintegral at Lullabot commentedAgreed, this looks good to me.
Comment #20
alexpottNeeds a leading slash and exception messages shouldn't end in a fullstop because they appear as part of the sentence when displayed. And it probably could be tested.
Given this is a bug fix and actually just provides a nicer way to break this is definitely eligible for 8.1.x
Comment #21
alexpottComment #22
arunkumarkHi,
As per the Comment #20 made a small change in timmillwood's patch.
Comment #23
tstoecklerPatch looks great, thanks @arunkumark!
Still needs tests, though, so setting back to "needs work" for now, now that the test bot has confirmed the patch is good.
Comment #24
xjm#20 was true during the beta phase for 8.1.x, but since the fix changes the error flow, we should target it for the development minor after the first release candidate of the previous minor. (I.e., it's not patch-eligible.)
Agreed on needing tests; they should be pretty simple to write I think?
Thanks everyone!
Comment #25
tstoeckler@xjm: Can you elaborate on what you mean by "changes the error flow"? Seems to me this is purely a DX-nicety and, thus, 8.2.x eligible (both before and after 8.2.0).
Comment #26
dawehnerI think @xjm points to the different of providing a fatal: call to undefined function vs. throwing an exception. As long we are not in PHP7 land, where those errors are maybe handled in a better way, replacing a fatal error with an exception is really the only sane way of doing it. One thing I would try to figure out: What do other places in core do here? Do they silently fail and just don't call the function (the render/theme/form systems should have a bunch of those examples). IMHO we should follow that example.
Comment #28
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commented@dawhener looking at the renderer it would just fatal in \Drupal\Core\Render\Renderer::render()
Throwing the exception still seems better than a fatal since we can test that behavior.
Note - patch #22 still applies to 8.4.x
Comment #29
dawehnerYeah a fatal is never what you want, IMHO.
Setting back to needs review, as the patch passes.
Comment #30
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedclosed this other as duplicate: #2547505: "allowed_values_function" doesn't use call_user_func()
Note from discussion with Berdir in IRC, you can only set in the field config a string for this, so you can use a string or static method but not an array.
If you try to save a field storage definition with an array callable you get an exception. So, it's probably fine to support any callable, but in practice (and for tests) we need only consider strings.
Here's with some added tests.
Comment #32
timmillwoodComment #33
pk188 CreditAttribution: pk188 at OpenSense Labs commentedRe rolled.
Comment #34
dawehnerWe should document when this is thrown.
Comment #37
joachim CreditAttribution: joachim as a volunteer commentedLooks good apart from:
$callable_name is not defined.
Do we need to use the long form of is_callable() here anyway?
Comment #38
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commentedComment #41
joachim CreditAttribution: joachim commentedThis should be postponed on #2982949: Introduce CallableResolver to help standardise the DX and error handling for callbacks across various subsystems.
Comment #42
joachim CreditAttribution: joachim commentedActually, I think this can be closed in favour of #2975503: allow FieldConfigInterface::setDefaultValueCallback() to accept a callback in service notation, which also depends on #2982949: Introduce CallableResolver to help standardise the DX and error handling for callbacks across various subsystems.
Static method notation works fine in versions of PHP that are now supported by Drupal 8. Eg:
Comment #49
Amber Himes MatzPer @joachim's comment in #42, looks like this issue should be closed as a duplicate in favor of #2975503: allow FieldConfigInterface::setDefaultValueCallback() to accept a callback in service notation. I'm closing this one and transferring credit over to that issue, as there was a lot of great discussion, review, patches, and triaging work here.
Triaged as part of the Bug Smash Initiative.
Comment #50
Amber Himes MatzComment #51
Amber Himes MatzSince credit was transferred to the other issue #2975503: allow FieldConfigInterface::setDefaultValueCallback() to accept a callback in service notation, removing the credit here.