2
votes

In Symfony2, there is some Twig module disabled by default. One of them is the debug extension, that adds {% debug %} tag (useful on a development environment).

To enable it, nothing really difficult, you add this service to your configuration :

  debug.twig.extension:
    class: Twig_Extensions_Extension_Debug
    tags:
      - { name: 'twig.extension' }

But how to enable the {% sandbox %} tag?

My issue is that the extension's constructor takes security policies :

public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false)
{
    $this->policy            = $policy;
    $this->sandboxedGlobally = $sandboxed;
}

By reading the twig documentation, I seen the way to do it natively (without Symfony2) :

$tags = array('if');
$filters = array('upper');
$methods = array(
    'Article' => array('getTitle', 'getBody'),
);
$properties = array(
    'Article' => array('title', 'body'),
);
$functions = array('range');
$policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions);
$sandbox = new Twig_Extension_Sandbox($policy);
$twig->addExtension($sandbox);

I can do something like that inside a service just before using the sandbox, but that's not as clear as the dependancy injection we're used to.

Is there a better / proper way to enable the twig's sandbox extension in Symfony2?

1

1 Answers

7
votes

Why not create a private service of the security policy:

parameters:
    twig.sandbox.tags:
        - if
    twig.sandbox.filters:
        - upper
    twig.sandbox.methods:
        Article: [getTitle, getBody]
    twig.sandbox.properties:
        Article: [title, body]
    twig.sandbox.functions:
        - range

twig.sandbox.policy:
    class: Twig_Sandbox_SecurityPolicy
    arguments:
        - %twig.sandbox.tags%
        - %twig.sandbox.filters%
        - %twig.sandbox.methods%
        - %twig.sandbox.properties%
        - %twig.sandbox.functions%
    public: false

You can then inject this service into the twig.sandbox.extension service:

twig.sandbox.extension:
    class: Twig_Extension_Sandbox
    arguments:
        - @twig.sandbox.policy
    tags:
        - { name: twig.extension }

Done. Marking the twig.sandbox.policy private ensures it won't be accessible using the container (it can still be injected into other services, but I think that's not an issue).

Disclaimer: I haven't tested this and it probably needs some tweaking before it actually works so don't copy paste!