Completed
Push — feature/bigfix_proxy_httploade... ( 5efe01 )
by Bastian
43:53 queued 29:53
created

I18nUtils   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 222
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 94.74%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 16
lcom 1
cbo 12
dl 0
loc 222
ccs 72
cts 76
cp 0.9474
rs 10
c 1
b 1
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A isTranslatableContext() 0 4 1
A getDefaultLanguage() 0 4 1
A __construct() 0 13 1
A getTranslatableDomain() 0 11 3
A getLanguages() 0 8 2
A getTranslatedField() 0 17 2
B findMatchingTranslatables() 0 33 2
B insertTranslatable() 0 40 4
1
<?php
2
/**
3
 * service for i18n stuff
4
 */
5
6
namespace Graviton\I18nBundle\Service;
7
8
use Graviton\DocumentBundle\Entity\ExtReference;
9
use Graviton\I18nBundle\Model\Translatable;
10
use Graviton\I18nBundle\Document\Translatable as TranslatableDocument;
11
use Graviton\I18nBundle\Document\TranslatableLanguage;
12
use Graviton\I18nBundle\Repository\LanguageRepository;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\Translation\TranslatorInterface;
15
16
/**
17
 * A service (meaning symfony service) providing some convenience stuff when dealing with our RestController
18
 * based services (meaning rest services).
19
 *
20
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
21
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
22
 * @link     http://swisscom.ch
23
 */
24
class I18nUtils
25
{
26
27
    /**
28
     * @var string
29
     */
30
    protected $defaultLanguage;
31
32
    /**
33
     * @var \Symfony\Component\Translation\TranslatorInterface
34
     */
35
    protected $translator;
36
37
    /**
38
     * @var \Graviton\I18nBundle\Model\Translatable
39
     */
40
    protected $translatable;
41
42
    /**
43
     * @var \Graviton\I18nBundle\Repository\LanguageRepository
44
     */
45
    protected $languageRepository;
46
47
    /**
48
     * @var \Symfony\Component\HttpFoundation\Request
49
     */
50
    protected $request;
51
52
    /**
53
     * Constructor
54
     *
55
     * @param string              $defaultLanguage    default language
56
     * @param TranslatorInterface $translator         Translator
57
     * @param Translatable        $translatable       translatable
58
     * @param LanguageRepository  $languageRepository lang repo
59
     * @param Request             $request            request
0 ignored issues
show
Documentation introduced by
Should the type for parameter $request not be null|Request?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
60
     */
61 165
    public function __construct(
62
        $defaultLanguage,
63
        TranslatorInterface $translator,
64
        Translatable $translatable,
65
        LanguageRepository $languageRepository,
66
        Request $request = null
67
    ) {
68 165
        $this->defaultLanguage = $defaultLanguage;
69 165
        $this->translator = $translator;
70 165
        $this->translatable = $translatable;
71 165
        $this->languageRepository = $languageRepository;
72 165
        $this->request = $request;
73 165
    }
74
75
    /**
76
     * Returns whether we are in a Translatable context. That means if we can determine a translation domain.
77
     *
78
     * @return bool true if yes, false if not
79
     */
80 82
    public function isTranslatableContext()
81
    {
82 82
        return (!is_null($this->getTranslatableDomain()));
83
    }
84
85
    /**
86
     * Returns the domain to use according to the current request.
87
     * If there is no valid request, null will be returned..
88
     *
89
     * @return string domain
90
     */
91 96
    public function getTranslatableDomain()
92
    {
93 96
        $ret = null;
94 96
        if ($this->request instanceof Request) {
95 83
            $uriParts = explode('/', substr($this->request->getRequestUri(), 1));
96 83
            if (isset($uriParts[0])) {
97 83
                $ret = $uriParts[0];
98
            }
99
        }
100 96
        return $ret;
101
    }
102
103
    /**
104
     * Returns the default/original language - is set by DIC param
105
     *
106
     * @return string default language
107
     */
108 83
    public function getDefaultLanguage()
109
    {
110 83
        return $this->defaultLanguage;
111
    }
112
113
    /**
114
     * Returns all languages as a simple flat array
115
     *
116
     * @return array array of language id's
117
     */
118 83
    public function getLanguages()
119
    {
120 83
        $languages = array();
121 83
        foreach ($this->languageRepository->findAll() as $lang) {
122 57
            $languages[] = $lang->getId();
123
        }
124 83
        return $languages;
125
    }
126
127
    /**
128
     * build a complete translated field
129
     *
130
     * @param string $value     value to translate
131
     * @param bool   $forClient if true, we look at languages header, false we render all languages
132
     *
133
     * @return array array with translated strings
134
     */
135 68
    public function getTranslatedField($value, $forClient = true)
136
    {
137 68
        $domain = $this->getTranslatableDomain();
138
139 68
        if ($forClient) {
140 68
            $languages = $this->request->attributes->get('languages');
141
        } else {
142
            $languages = $this->getLanguages();
143
        }
144
145 68
        return array_map(
146
            function ($language) use ($value, $domain) {
147 68
                return $this->translator->trans($value, array(), $domain, $language);
148 68
            },
149
            $languages
150
        );
151
    }
152
153
    /**
154
     * This function allows to search for existing translations from a source
155
     * language, probably using a wildcard
156
     *
157
     * @param string  $value        the translated string
158
     * @param string  $sourceLocale a source locale
159
     * @param boolean $useWildCard  if we should search wildcard or not
160
     *
161
     * @return array matching Translatables
162
     */
163 5
    public function findMatchingTranslatables($value, $sourceLocale, $useWildCard = false)
164
    {
165
        // i need to use a queryBuilder as the repository doesn't let me do regex queries (i guess so..)
166 5
        $builder = $this->translatable->getRepository()->createQueryBuilder();
167
        $builder
168 5
            ->field('domain')->equals($this->getTranslatableDomain())
169 5
            ->field('locale')->equals($sourceLocale);
170
171 5
        if ($useWildCard === true) {
172 2
            $value = new \MongoRegex($value);
173
        }
174
175
        /*
176
         * we have 2 cases to match
177
         * - 'translated' is set and matches
178
         * - 'translated' is not present, so 'original' can match (as this is inserted 'virtually')
179
         */
180 5
        $builder->addAnd(
181 5
            $builder->expr()
182 5
                ->addOr(
183 5
                    $builder->expr()->field('translated')->equals($value)
184
                )
185 5
                ->addOr(
186 5
                    $builder->expr()
187 5
                        ->field('translated')->equals(null)
188 5
                        ->field('original')->equals($value)
189
                )
190
        );
191
192 5
        $query = $builder->getQuery();
193
194 5
        return $query->execute()->toArray();
195
    }
196
197
    /**
198
     * [In|Up]serts a Translatable object using an array with language strings.
199
     *
200
     * @param array $values array with language strings; key should be language id
201
     * @throws \Exception
202
     *
203
     * @return void
204
     */
205 82
    public function insertTranslatable(array $values)
206
    {
207 82
        if (!isset($values[$this->getDefaultLanguage()])) {
208
            throw new \Exception(
209
                sprintf(
210
                    'Creating new Translatable without "%s" key is not support yet.',
211
                    $this->getDefaultLanguage()
212
                )
213
            );
214
        }
215
216 82
        $original = $values[$this->getDefaultLanguage()];
217
218 82
        if ($this->isTranslatableContext()) {
219 40
            $languages = $this->getLanguages();
220 40
            \array_walk(
221
                $languages,
222 40
                function ($locale) use ($original, $values) {
223 23
                    $isLocalized = false;
224 23
                    $translated = '';
225 23
                    $domain = $this->getTranslatableDomain();
226 23
                    if (array_key_exists($locale, $values)) {
227 23
                        $translated = $values[$locale];
228 23
                        $isLocalized = true;
229
                    }
230 23
                    $translatable = new TranslatableDocument();
231 23
                    $translatable->setId($domain . '-' . $locale . '-' . $original);
232 23
                    $translatable->setLocale($locale);
233 23
                    $translatable->setDomain($domain);
234 23
                    $translatable->setOriginal($original);
235 23
                    $translatable->setTranslated($translated);
236 23
                    $translatable->setIsLocalized($isLocalized);
237 23
                    $translatableLang = new TranslatableLanguage();
238 23
                    $translatableLang->setRef(ExtReference::create('Language', $locale));
239 23
                    $translatable->setLanguage($translatableLang);
240 23
                    $this->translatable->insertRecord($translatable);
241 40
                }
242
            );
243
        }
244 82
    }
245
}
246