mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-30 20:16:45 +00:00
Allow inherited magic method to still run with calling class
If a static method cannot be resolved to the calling class, but the calling class has, or inherits, a `__callStatic` handler, this allows the `__callStatic` handler to be used with the calling class, and not the inherited class as would occur with reflection. This allows systems such as Laravel facades to still work. Fixes https://github.com/twigphp/Twig/issues/3716
This commit is contained in:
committed by
Nicolas Grekas
parent
c953a77b23
commit
d1457a40b6
@@ -305,8 +305,7 @@ abstract class CallExpression extends AbstractExpression
|
||||
$callable = [$object, $r->name];
|
||||
$callableName = (\function_exists('get_debug_type') ? get_debug_type($object) : \get_class($object)).'::'.$r->name;
|
||||
} elseif ($class = $r->getClosureScopeClass()) {
|
||||
$callable = [$class, $r->name];
|
||||
$callableName = $class.'::'.$r->name;
|
||||
$callableName = (\is_array($callable) ? $callable[0] : $class->name).'::'.$r->name;
|
||||
} else {
|
||||
$callable = $callableName = $r->name;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ class FilterTest extends NodeTestCase
|
||||
$environment->addFilter(new TwigFilter('bar', 'twig_tests_filter_dummy', ['needs_environment' => true]));
|
||||
$environment->addFilter(new TwigFilter('bar_closure', \Closure::fromCallable(twig_tests_filter_dummy::class), ['needs_environment' => true]));
|
||||
$environment->addFilter(new TwigFilter('barbar', 'Twig\Tests\Node\Expression\twig_tests_filter_barbar', ['needs_context' => true, 'is_variadic' => true]));
|
||||
$environment->addFilter(new TwigFilter('magic_static', __NAMESPACE__.'\ChildMagicCallStub::magicStaticCall'));
|
||||
|
||||
$extension = new class() extends AbstractExtension {
|
||||
public function getFilters(): array
|
||||
@@ -135,6 +136,9 @@ class FilterTest extends NodeTestCase
|
||||
$node = $this->createFilter($string, 'foobar');
|
||||
$tests[] = [$node, '$this->env->getFilter(\'foobar\')->getCallable()("abc")', $environment];
|
||||
|
||||
$node = $this->createFilter($string, 'magic_static');
|
||||
$tests[] = [$node, 'Twig\Tests\Node\Expression\ChildMagicCallStub::magicStaticCall("abc")', $environment];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
@@ -190,3 +194,28 @@ function twig_tests_filter_dummy()
|
||||
function twig_tests_filter_barbar($context, $string, $arg1 = null, $arg2 = null, array $args = [])
|
||||
{
|
||||
}
|
||||
|
||||
class ChildMagicCallStub extends ParentMagicCallStub
|
||||
{
|
||||
public static function identifier()
|
||||
{
|
||||
return 'child';
|
||||
}
|
||||
}
|
||||
|
||||
class ParentMagicCallStub
|
||||
{
|
||||
public static function identifier()
|
||||
{
|
||||
throw new \Exception('Identifier has not been defined');
|
||||
}
|
||||
|
||||
public static function __callStatic($method, $arguments)
|
||||
{
|
||||
if ('magicStaticCall' !== $method) {
|
||||
throw new \BadMethodCallException('Unexpected call to __callStatic');
|
||||
}
|
||||
|
||||
return 'inherited_static_magic_'.static::identifier().'_'.$arguments[0];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user