Completed
Push — master ( f2dfe9...84d91c )
by André
35:37 queued 16:15
created

LanguageService::buildDomainObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
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)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
75
            throw new InvalidArgumentValue('name', $languageCreateStruct->name, 'LanguageCreateStruct');
76
        }
77
78 View Code Duplication
        if (!is_string($languageCreateStruct->languageCode) || empty($languageCreateStruct->languageCode)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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)) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
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)) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
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)) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
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)) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
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)) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
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