Twig icon indicating copy to clipboard operation
Twig copied to clipboard

Using __call in RuntimeExtensionInterface

Open nlemoine opened this issue 3 years ago • 0 comments

Hi!

I'm facing an issue related to #3451

Consider the following example:

class SomeExtension extends AbstractExtension
{
    private array $filters = [
         'filter1',
         'filter2',
         'filter3',
         // and so on...
    ];

    public function getFilters(): array
    {
        $filters = [];
        foreach ($this->filters as $filter) {
            $filters[] = new TwigFilter(
                $filter,
                [SomeRuntime::class, $filter], // Don't work
                // ["SomeRuntime::$filter"], // Don't work either
                ['is_variadic' => true]
            );
        }

        return $filters;
    }
}

class SomeRuntime implements RuntimeExtensionInterface
{
    private Service $service;

    public function __construct(Service $service)
    {
        $this->service = $service;
    }

    public function __call($name, array $arguments = [])
    {
        $object = $this->service->create($arguments[0]);
        return $object->$name(...$arguments)
    }
}

Note that in my real world example, I make use of the ContainerRuntimeLoader to inject Service in my runtime but I don't think it's relevant here.

Sadly you can't use __call in a RuntimeExtensionInterface because of https://github.com/twigphp/Twig/blob/871747851f17892de24dda275060ad88369baba4/src/Node/Expression/CallExpression.php#L296-L299

Whereas this approach works fine if I use a regular AbstractExtension, not a RuntimeExtensionInterface extension.

It would be great that runtime extension handles this use case too.

nlemoine avatar Jan 19 '22 16:01 nlemoine