1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing the eZ\Publish\Core\Repository\LanguageService class. |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
8
|
|
|
*/ |
9
|
|
|
namespace eZ\Publish\Core\Repository; |
10
|
|
|
|
11
|
|
|
use eZ\Publish\API\Repository\LanguageService as LanguageServiceInterface; |
12
|
|
|
use eZ\Publish\SPI\Persistence\Content\Language\Handler; |
13
|
|
|
use eZ\Publish\API\Repository\Repository as RepositoryInterface; |
14
|
|
|
use eZ\Publish\API\Repository\Values\Content\LanguageCreateStruct; |
15
|
|
|
use eZ\Publish\SPI\Persistence\Content\Language as SPILanguage; |
16
|
|
|
use eZ\Publish\SPI\Persistence\Content\Language\CreateStruct; |
17
|
|
|
use eZ\Publish\API\Repository\Values\Content\Language; |
18
|
|
|
use eZ\Publish\API\Repository\Exceptions\NotFoundException as APINotFoundException; |
19
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue; |
20
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException; |
21
|
|
|
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException; |
22
|
|
|
use LogicException; |
23
|
|
|
use Exception; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Language service, used for language operations. |
27
|
|
|
*/ |
28
|
|
|
class LanguageService implements LanguageServiceInterface |
29
|
|
|
{ |
30
|
|
|
/** |
31
|
|
|
* @var \eZ\Publish\API\Repository\Repository |
32
|
|
|
*/ |
33
|
|
|
protected $repository; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var \eZ\Publish\SPI\Persistence\Content\Language\Handler |
37
|
|
|
*/ |
38
|
|
|
protected $languageHandler; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var array |
42
|
|
|
*/ |
43
|
|
|
protected $settings; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Setups service with reference to repository object that created it & corresponding handler. |
47
|
|
|
* |
48
|
|
|
* @param \eZ\Publish\API\Repository\Repository $repository |
49
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Language\Handler $languageHandler |
50
|
|
|
* @param array $settings |
51
|
|
|
*/ |
52
|
|
|
public function __construct(RepositoryInterface $repository, Handler $languageHandler, array $settings = array()) |
53
|
|
|
{ |
54
|
|
|
$this->repository = $repository; |
55
|
|
|
$this->languageHandler = $languageHandler; |
56
|
|
|
// Union makes sure default settings are ignored if provided in argument |
57
|
|
|
$this->settings = $settings + array( |
58
|
|
|
'languages' => array('eng-GB'), |
59
|
|
|
); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Creates the a new Language in the content repository. |
64
|
|
|
* |
65
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If user does not have access to content translations |
66
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the languageCode already exists |
67
|
|
|
* |
68
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\LanguageCreateStruct $languageCreateStruct |
69
|
|
|
* |
70
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language |
71
|
|
|
*/ |
72
|
|
|
public function createLanguage(LanguageCreateStruct $languageCreateStruct) |
73
|
|
|
{ |
74
|
|
View Code Duplication |
if (!is_string($languageCreateStruct->name) || empty($languageCreateStruct->name)) { |
|
|
|
|
75
|
|
|
throw new InvalidArgumentValue('name', $languageCreateStruct->name, 'LanguageCreateStruct'); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
View Code Duplication |
if (!is_string($languageCreateStruct->languageCode) || empty($languageCreateStruct->languageCode)) { |
|
|
|
|
79
|
|
|
throw new InvalidArgumentValue('languageCode', $languageCreateStruct->languageCode, 'LanguageCreateStruct'); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
if (!is_bool($languageCreateStruct->enabled)) { |
83
|
|
|
throw new InvalidArgumentValue('enabled', $languageCreateStruct->enabled, 'LanguageCreateStruct'); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
if (!$this->repository->canUser('content', 'translations', $languageCreateStruct)) { |
|
|
|
|
87
|
|
|
throw new UnauthorizedException('content', 'translations'); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
try { |
91
|
|
|
if ($this->loadLanguage($languageCreateStruct->languageCode) !== null) { |
92
|
|
|
throw new InvalidArgumentException('languageCreateStruct', 'language with specified language code already exists'); |
93
|
|
|
} |
94
|
|
|
} catch (APINotFoundException $e) { |
95
|
|
|
// Do nothing |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
$createStruct = new CreateStruct( |
99
|
|
|
array( |
100
|
|
|
'languageCode' => $languageCreateStruct->languageCode, |
101
|
|
|
'name' => $languageCreateStruct->name, |
102
|
|
|
'isEnabled' => $languageCreateStruct->enabled, |
103
|
|
|
) |
104
|
|
|
); |
105
|
|
|
|
106
|
|
|
$this->repository->beginTransaction(); |
107
|
|
|
try { |
108
|
|
|
$createdLanguage = $this->languageHandler->create($createStruct); |
109
|
|
|
$this->repository->commit(); |
110
|
|
|
} catch (Exception $e) { |
111
|
|
|
$this->repository->rollback(); |
112
|
|
|
throw $e; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
return $this->buildDomainObject($createdLanguage); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Changes the name of the language in the content repository. |
120
|
|
|
* |
121
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if languageCode argument |
122
|
|
|
* is not string |
123
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If user does not have access to content translations |
124
|
|
|
* |
125
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Language $language |
126
|
|
|
* @param string $newName |
127
|
|
|
* |
128
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language |
129
|
|
|
*/ |
130
|
|
|
public function updateLanguageName(Language $language, $newName) |
131
|
|
|
{ |
132
|
|
|
if (!is_string($newName) || empty($newName)) { |
133
|
|
|
throw new InvalidArgumentValue('newName', $newName); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
if (!$this->repository->canUser('content', 'translations', $language)) { |
|
|
|
|
137
|
|
|
throw new UnauthorizedException('content', 'translations'); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
$loadedLanguage = $this->loadLanguageById($language->id); |
141
|
|
|
|
142
|
|
|
$updateLanguageStruct = new SPILanguage( |
143
|
|
|
array( |
144
|
|
|
'id' => $loadedLanguage->id, |
145
|
|
|
'languageCode' => $loadedLanguage->languageCode, |
146
|
|
|
'name' => $newName, |
147
|
|
|
'isEnabled' => $loadedLanguage->enabled, |
148
|
|
|
) |
149
|
|
|
); |
150
|
|
|
|
151
|
|
|
$this->repository->beginTransaction(); |
152
|
|
|
try { |
153
|
|
|
$this->languageHandler->update($updateLanguageStruct); |
154
|
|
|
$this->repository->commit(); |
155
|
|
|
} catch (Exception $e) { |
156
|
|
|
$this->repository->rollback(); |
157
|
|
|
throw $e; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
return $this->loadLanguageById($loadedLanguage->id); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Enables a language. |
165
|
|
|
* |
166
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If user does not have access to content translations |
167
|
|
|
* |
168
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Language $language |
169
|
|
|
* |
170
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language |
171
|
|
|
*/ |
172
|
|
View Code Duplication |
public function enableLanguage(Language $language) |
173
|
|
|
{ |
174
|
|
|
if (!$this->repository->canUser('content', 'translations', $language)) { |
|
|
|
|
175
|
|
|
throw new UnauthorizedException('content', 'translations'); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
$loadedLanguage = $this->loadLanguageById($language->id); |
179
|
|
|
|
180
|
|
|
$updateLanguageStruct = new SPILanguage( |
181
|
|
|
array( |
182
|
|
|
'id' => $loadedLanguage->id, |
183
|
|
|
'languageCode' => $loadedLanguage->languageCode, |
184
|
|
|
'name' => $loadedLanguage->name, |
185
|
|
|
'isEnabled' => true, |
186
|
|
|
) |
187
|
|
|
); |
188
|
|
|
|
189
|
|
|
$this->repository->beginTransaction(); |
190
|
|
|
try { |
191
|
|
|
$this->languageHandler->update($updateLanguageStruct); |
192
|
|
|
$this->repository->commit(); |
193
|
|
|
} catch (Exception $e) { |
194
|
|
|
$this->repository->rollback(); |
195
|
|
|
throw $e; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
return $this->loadLanguageById($loadedLanguage->id); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Disables a language. |
203
|
|
|
* |
204
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If user does not have access to content translations |
205
|
|
|
* |
206
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Language $language |
207
|
|
|
* |
208
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language |
209
|
|
|
*/ |
210
|
|
View Code Duplication |
public function disableLanguage(Language $language) |
211
|
|
|
{ |
212
|
|
|
if (!$this->repository->canUser('content', 'translations', $language)) { |
|
|
|
|
213
|
|
|
throw new UnauthorizedException('content', 'translations'); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
$loadedLanguage = $this->loadLanguageById($language->id); |
217
|
|
|
|
218
|
|
|
$updateLanguageStruct = new SPILanguage( |
219
|
|
|
array( |
220
|
|
|
'id' => $loadedLanguage->id, |
221
|
|
|
'languageCode' => $loadedLanguage->languageCode, |
222
|
|
|
'name' => $loadedLanguage->name, |
223
|
|
|
'isEnabled' => false, |
224
|
|
|
) |
225
|
|
|
); |
226
|
|
|
|
227
|
|
|
$this->repository->beginTransaction(); |
228
|
|
|
try { |
229
|
|
|
$this->languageHandler->update($updateLanguageStruct); |
230
|
|
|
$this->repository->commit(); |
231
|
|
|
} catch (Exception $e) { |
232
|
|
|
$this->repository->rollback(); |
233
|
|
|
throw $e; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
return $this->loadLanguageById($loadedLanguage->id); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Loads a Language from its language code ($languageCode). |
241
|
|
|
* |
242
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if languageCode argument |
243
|
|
|
* is not string |
244
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if language could not be found |
245
|
|
|
* |
246
|
|
|
* @param string $languageCode |
247
|
|
|
* |
248
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language |
249
|
|
|
*/ |
250
|
|
|
public function loadLanguage($languageCode) |
251
|
|
|
{ |
252
|
|
|
if (!is_string($languageCode) || empty($languageCode)) { |
253
|
|
|
throw new InvalidArgumentException('languageCode', 'language code has an invalid value'); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
$language = $this->languageHandler->loadByLanguageCode($languageCode); |
257
|
|
|
|
258
|
|
|
return $this->buildDomainObject($language); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Loads all Languages. |
263
|
|
|
* |
264
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language[] |
265
|
|
|
*/ |
266
|
|
|
public function loadLanguages() |
267
|
|
|
{ |
268
|
|
|
$languages = $this->languageHandler->loadAll(); |
269
|
|
|
|
270
|
|
|
$returnArray = array(); |
271
|
|
|
foreach ($languages as $language) { |
272
|
|
|
$returnArray[] = $this->buildDomainObject($language); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
return $returnArray; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Loads a Language by its id ($languageId). |
280
|
|
|
* |
281
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if language could not be found |
282
|
|
|
* |
283
|
|
|
* @param mixed $languageId |
284
|
|
|
* |
285
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language |
286
|
|
|
*/ |
287
|
|
|
public function loadLanguageById($languageId) |
288
|
|
|
{ |
289
|
|
|
$language = $this->languageHandler->load($languageId); |
290
|
|
|
|
291
|
|
|
return $this->buildDomainObject($language); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* {@inheritdoc} |
296
|
|
|
*/ |
297
|
|
|
public function loadLanguageListByCode(array $languageCodes): iterable |
298
|
|
|
{ |
299
|
|
|
$languages = $this->languageHandler->loadListByLanguageCodes($languageCodes); |
300
|
|
|
|
301
|
|
|
$returnArray = array(); |
302
|
|
|
foreach ($languages as $language) { |
303
|
|
|
$returnArray[$language->languageCode] = $this->buildDomainObject($language); |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
return $returnArray; |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* {@inheritdoc} |
311
|
|
|
*/ |
312
|
|
|
public function loadLanguageListById(array $languageIds): iterable |
313
|
|
|
{ |
314
|
|
|
$languages = $this->languageHandler->loadList($languageIds); |
315
|
|
|
|
316
|
|
|
$returnArray = array(); |
317
|
|
|
foreach ($languages as $language) { |
318
|
|
|
$returnArray[$language->id] = $this->buildDomainObject($language); |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
return $returnArray; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
/** |
325
|
|
|
* Deletes a language from content repository. |
326
|
|
|
* |
327
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
328
|
|
|
* if language can not be deleted |
329
|
|
|
* because it is still assigned to some content / type / (...). |
330
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException If user does not have access to content translations |
331
|
|
|
* |
332
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Language $language |
333
|
|
|
*/ |
334
|
|
View Code Duplication |
public function deleteLanguage(Language $language) |
335
|
|
|
{ |
336
|
|
|
if (!$this->repository->canUser('content', 'translations', $language)) { |
|
|
|
|
337
|
|
|
throw new UnauthorizedException('content', 'translations'); |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
$loadedLanguage = $this->loadLanguageById($language->id); |
341
|
|
|
|
342
|
|
|
$this->repository->beginTransaction(); |
343
|
|
|
try { |
344
|
|
|
$this->languageHandler->delete($loadedLanguage->id); |
345
|
|
|
$this->repository->commit(); |
346
|
|
|
} catch (LogicException $e) { |
347
|
|
|
$this->repository->rollback(); |
348
|
|
|
throw new InvalidArgumentException('language', $e->getMessage(), $e); |
349
|
|
|
} catch (Exception $e) { |
350
|
|
|
$this->repository->rollback(); |
351
|
|
|
throw $e; |
352
|
|
|
} |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Returns a configured default language code. |
357
|
|
|
* |
358
|
|
|
* @return string |
359
|
|
|
*/ |
360
|
|
|
public function getDefaultLanguageCode() |
361
|
|
|
{ |
362
|
|
|
return $this->settings['languages'][0]; |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
/** |
366
|
|
|
* Returns a configured list of prioritized languageCodes. |
367
|
|
|
* |
368
|
|
|
* |
369
|
|
|
* @return string[] |
370
|
|
|
*/ |
371
|
|
|
public function getPrioritizedLanguageCodeList() |
372
|
|
|
{ |
373
|
|
|
return $this->settings['languages']; |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* Instantiates an object to be used for creating languages. |
378
|
|
|
* |
379
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\LanguageCreateStruct |
380
|
|
|
*/ |
381
|
|
|
public function newLanguageCreateStruct() |
382
|
|
|
{ |
383
|
|
|
return new LanguageCreateStruct(); |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* Builds Language domain object from ValueObject returned by Persistence API. |
388
|
|
|
* |
389
|
|
|
* @param \eZ\Publish\SPI\Persistence\Content\Language $spiLanguage |
390
|
|
|
* |
391
|
|
|
* @return \eZ\Publish\API\Repository\Values\Content\Language |
392
|
|
|
*/ |
393
|
|
|
protected function buildDomainObject(SPILanguage $spiLanguage) |
394
|
|
|
{ |
395
|
|
|
return new Language( |
396
|
|
|
array( |
397
|
|
|
'id' => $spiLanguage->id, |
398
|
|
|
'languageCode' => $spiLanguage->languageCode, |
399
|
|
|
'name' => $spiLanguage->name, |
400
|
|
|
'enabled' => $spiLanguage->isEnabled, |
401
|
|
|
) |
402
|
|
|
); |
403
|
|
|
} |
404
|
|
|
} |
405
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.