1<?php
2/**
3 * A class for translation nodes that can be translated with customizable functions.
4 *
5 * @author Jaime Pérez Crespo
6 */
7
8namespace JaimePerez\TwigConfigurableI18n\Twig\Extensions\Node;
9
10use ReflectionClass;
11use Twig_Compiler;
12use Twig_Extensions_Node_Trans;
13
14class Trans extends Twig_Extensions_Node_Trans
15{
16    /**
17     * Compiles the node to PHP.
18     *
19     * If JaimePerez\TwigConfigurableI18n\Twig\Environment was used to configure Twig, and the version of
20     * Twig_Extensions_Extension_I18n allows it, we will try to change all calls to the default translation methods
21     * to whatever is configured in the environment.
22     *
23     * @param Twig_Compiler $compiler A Twig_Compiler instance
24     */
25    public function compile(Twig_Compiler $compiler)
26    {
27        parent::compile($compiler);
28
29        // get the reflection class for Twig_Compiler and evaluate if we can parasite it
30        $class = new ReflectionClass('Twig_Compiler');
31        if (!$class->hasProperty('source')) {
32            // the source must have changed, we don't have the "source" property, so nothing we can do here...
33            return;
34        }
35
36        // looks doable, set the "source" property accessible
37        $property = $class->getProperty('source');
38        $property->setAccessible(true);
39
40        // now, if we have proper configuration, rename the calls to gettext with the ones configured in the environment
41        $env = $compiler->getEnvironment();
42        if (is_a($env, '\JaimePerez\TwigConfigurableI18n\Twig\Environment')) {
43            /** @var \JaimePerez\TwigConfigurableI18n\Twig\Environment $env */
44            $options = $env->getOptions();
45            $source = $compiler->getSource();
46            if (array_key_exists('translation_function', $options) &&
47                is_callable($options['translation_function'], false, $callable)
48            ) {
49                $source = preg_replace('/([^\w_$])gettext\(/', '$1'.$callable.'(', $source);
50                $property->setValue($compiler, $source);
51            }
52            if (array_key_exists('translation_function_plural', $options) &&
53                is_callable($options['translation_function_plural'], false, $callable)
54            ) {
55                $source = preg_replace(
56                    '/([^\w_$])ngettext\(/',
57                    '$1'.$callable.'(',
58                    $source
59                );
60                $property->setValue($compiler, $source);
61            }
62        }
63    }
64}
65