CustomTranslateExtension::_()   A
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 6.0493

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 9
c 2
b 0
f 0
nc 8
nop 3
dl 0
loc 14
ccs 8
cts 9
cp 0.8889
crap 6.0493
rs 9.2222
1
<?php
2
3
namespace PSFS\base\extension;
4
5
use PSFS\base\config\Config;
6
use PSFS\base\Logger;
7
use PSFS\base\Security;
8
use PSFS\base\types\helpers\I18nHelper;
9
use PSFS\base\types\helpers\Inspector;
10
use PSFS\base\types\traits\SingletonTrait;
11
use Twig\Extension\AbstractExtension;
12
use Twig\TokenParser\BlockTokenParser;
13
use Twig\TwigFilter;
14
15
/**
16
 * Class CustomTranslateExtension
17
 * @package PSFS\base\extension
18
 */
19
class CustomTranslateExtension extends AbstractExtension
20
{
21
    use SingletonTrait;
22
23
    const CUSTOM_LOCALE_SESSION_KEY = '__PSFS_CUSTOM_LOCALE_KEY__';
24
    const LOCALE_CACHED_VERSION = '__PSFS_LOCALE_VERSION__';
25
    const LOCALE_CACHED_TAG = '__PSFS_TRANSLATIONS__';
26
27
    /**
28
     * @var array
29
     */
30
    protected static $translations = [];
31
    /**
32
     * @var string
33
     */
34
    protected static $locale = 'es_ES';
35
    /**
36
     * @var bool
37
     */
38
    protected static $generate = false;
39
    /**
40
     * @var string
41
     */
42
    protected static $filename = '';
43
44
    /**
45
     * @return array|mixed
46
     */
47 2
    protected static function extractBaseTranslations()
48
    {
49
        // Gather always the base translations
50 2
        $standardTranslations = [];
51 2
        self::$filename = implode(DIRECTORY_SEPARATOR, [LOCALE_DIR, 'custom', self::$locale . '.json']);
52 2
        if (file_exists(self::$filename)) {
53 2
            $standardTranslations = json_decode(file_get_contents(self::$filename), true);
54
        }
55 2
        return $standardTranslations;
56
    }
57
58
    /**
59
     * @param string $customKey
60
     * @param bool $forceReload
61
     * @param bool $useBase
62
     */
63 2
    protected static function translationsCheckLoad($customKey = null, $forceReload = false, $useBase = false)
64
    {
65 2
        Inspector::stats('[translationsCheckLoad] Start checking translations load', Inspector::SCOPE_DEBUG);
66 2
        $session = Security::getInstance();
67 2
        $session_locale = $session->getSessionKey(I18nHelper::PSFS_SESSION_LANGUAGE_KEY);
68 2
        self::$locale = $forceReload ? $session_locale : I18nHelper::extractLocale($session_locale);
69 2
        $version = $session->getSessionKey(self::LOCALE_CACHED_VERSION);
70 2
        $configVersion = self::$locale . '_' . Config::getParam('cache.var', 'v1');
71 2
        if ($forceReload) {
72 1
            Inspector::stats('[translationsCheckLoad] Force translations reload', Inspector::SCOPE_DEBUG);
73 1
            self::dropInstance();
74 1
            $version = null;
75 1
            self::$translations = [];
76
        }
77 2
        if (count(self::$translations) === 0) {
78 2
            Inspector::stats('[translationsCheckLoad] Extracting translations', Inspector::SCOPE_DEBUG);
79 2
            self::$generate = (boolean)Config::getParam('i18n.autogenerate', false);
80 2
            if (null !== $version && $version === $configVersion) {
81
                Inspector::stats('[translationsCheckLoad] Translations loaded from session', Inspector::SCOPE_DEBUG);
82
                self::$translations = $session->getSessionKey(self::LOCALE_CACHED_TAG);
83
            } else {
84 2
                if (!$useBase) {
85 2
                    $customKey = $customKey ?: $session->getSessionKey(self::CUSTOM_LOCALE_SESSION_KEY);
86
                }
87 2
                $standardTranslations = self::extractBaseTranslations();
88
                // If the project has custom translations, gather them
89 2
                if (null !== $customKey) {
90
                    Logger::log('[' . self::class . '] Custom key detected: ' . $customKey, LOG_INFO);
91
                    self::$filename = implode(DIRECTORY_SEPARATOR, [LOCALE_DIR, 'custom', $customKey, self::$locale . '.json']);
92
                }
93
                // Finally we merge base and custom translations to complete all the i18n set
94 2
                if (file_exists(self::$filename)) {
95 2
                    Logger::log('[' . self::class . '] Custom locale detected: ' . $customKey . ' [' . self::$locale . ']', LOG_INFO);
96 2
                    self::$translations = array_merge($standardTranslations, json_decode(file_get_contents(self::$filename), true));
97 2
                    $session->setSessionKey(self::LOCALE_CACHED_TAG, self::$translations);
98 2
                    $session->setSessionKey(self::LOCALE_CACHED_VERSION, $configVersion);
99
                } elseif (null !== $customKey) {
100
                    self::translationsCheckLoad(null, $forceReload, true);
101
                }
102
            }
103
        }
104 2
        Inspector::stats('[translationsCheckLoad] Translations loaded', Inspector::SCOPE_DEBUG);
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 1
    public function getTokenParsers()
111
    {
112 1
        return [new BlockTokenParser()];
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 2
    public function getFilters()
119
    {
120 1
        return array(
121 1
            new TwigFilter('trans', function ($message) {
122 2
                return self::_($message);
123 1
            }),
124 1
        );
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function getName()
131
    {
132
        return 'PSFSi18n';
133
    }
134
135
    /**
136
     * @param $message
137
     * @param string $customKey
138
     * @param bool $forceReload
139
     * @return mixed|string
140
     */
141 12
    public static function _($message, $customKey = null, $forceReload = false)
142
    {
143 12
        if (0 === count(self::$translations) || $forceReload) {
144 2
            self::translationsCheckLoad($customKey, $forceReload);
145
        }
146 12
        if (is_array(self::$translations) && array_key_exists($message, self::$translations)) {
147 9
            $translation = self::$translations[$message];
148
        } else {
149 4
            $translation = gettext($message);
150
        }
151 12
        if (self::$generate) {
152
            self::generate($message, $translation);
153
        }
154 12
        return $translation;
155
    }
156
157
    /**
158
     * @param string $message
159
     * @param string $translation
160
     */
161
    protected static function generate($message, $translation)
162
    {
163
        if (!array_key_exists($message, self::$translations)) {
164
            self::$translations[$message] = $translation;
165
        }
166
        file_put_contents(self::$filename, json_encode(array_unique(self::$translations), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
167
    }
168
}
169