Completed
Push — 6.13 ( 878d09...f11ecd )
by
unknown
26:52
created

Repository   F

Complexity

Total Complexity 79

Size/Duplication

Total Lines 1038
Duplicated Lines 4.24 %

Coupling/Cohesion

Components 1
Dependencies 33

Importance

Changes 0
Metric Value
dl 44
loc 1038
rs 1.528
c 0
b 0
f 0
wmc 79
lcom 1
cbo 33

37 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 50 5
A getCurrentUser() 0 10 2
A getCurrentUserReference() 0 4 1
A setCurrentUser() 0 17 3
A sudo() 0 7 2
A hasAccess() 0 4 1
A canUser() 0 16 4
A getContentService() 18 18 2
A getContentLanguageService() 0 14 2
A getContentTypeService() 17 17 2
A getLocationService() 0 18 2
A getTrashService() 0 15 2
A getSectionService() 0 14 2
A getUserService() 0 14 2
A getURLAliasService() 0 15 2
A getURLWildcardService() 0 14 2
A getURLService() 0 13 2
A getObjectStateService() 0 14 2
A getRoleService() 0 16 2
A getLimitationService() 0 10 2
A getRoleDomainMapper() 0 10 2
A getSearchService() 0 17 2
A getFieldTypeService() 0 10 2
A getPermissionResolver() 0 4 1
A getFieldTypeRegistry() 0 10 2
A getNameableFieldTypeRegistry() 0 10 2
A getNameSchemaService() 0 15 2
A getRelationProcessor() 0 4 1
A getDomainMapper() 0 16 2
A getContentTypeDomainMapper() 0 13 2
A getPermissionCriterionResolver() 0 4 1
A getCachedPermissionsResolver() 0 19 2
A beginTransaction() 0 7 1
B commit() 0 29 7
A rollback() 0 11 2
A commitEvent() 0 9 2
A createDateTime() 9 9 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Repository often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Repository, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\Core\Repository;
8
9
use eZ\Publish\API\Repository\Repository as RepositoryInterface;
10
use eZ\Publish\API\Repository\Values\ValueObject;
11
use eZ\Publish\API\Repository\Values\User\User;
12
use eZ\Publish\API\Repository\Values\User\UserReference as APIUserReference;
13
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue;
14
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentType;
15
use eZ\Publish\Core\Repository\Helper\RelationProcessor;
16
use eZ\Publish\Core\Repository\Permission\CachedPermissionService;
17
use eZ\Publish\Core\Repository\Permission\PermissionCriterionResolver;
18
use eZ\Publish\Core\Repository\Values\User\UserReference;
19
use eZ\Publish\Core\Search\Common\BackgroundIndexer;
20
use eZ\Publish\SPI\Persistence\Handler as PersistenceHandler;
21
use eZ\Publish\SPI\Search\Handler as SearchHandler;
22
use Exception;
23
use Psr\Log\LoggerInterface;
24
use Psr\Log\NullLogger;
25
use RuntimeException;
26
27
/**
28
 * Repository class.
29
 */
30
class Repository implements RepositoryInterface
31
{
32
    /**
33
     * Repository Handler object.
34
     *
35
     * @var \eZ\Publish\SPI\Persistence\Handler
36
     */
37
    protected $persistenceHandler;
38
39
    /**
40
     * Instance of main Search Handler.
41
     *
42
     * @var \eZ\Publish\SPI\Search\Handler
43
     */
44
    protected $searchHandler;
45
46
    /**
47
     * @deprecated since 6.6, to be removed. Current user handling is moved to PermissionResolver.
48
     *
49
     * Currently logged in user object if already loaded.
50
     *
51
     * @var \eZ\Publish\API\Repository\Values\User\User|null
52
     */
53
    protected $currentUser;
54
55
    /**
56
     * @deprecated since 6.6, to be removed. Current user handling is moved to PermissionResolver.
57
     *
58
     * Currently logged in user reference for permission purposes.
59
     *
60
     * @var \eZ\Publish\API\Repository\Values\User\UserReference
61
     */
62
    protected $currentUserRef;
63
64
    /**
65
     * Instance of content service.
66
     *
67
     * @var \eZ\Publish\API\Repository\ContentService
68
     */
69
    protected $contentService;
70
71
    /**
72
     * Instance of section service.
73
     *
74
     * @var \eZ\Publish\API\Repository\SectionService
75
     */
76
    protected $sectionService;
77
78
    /**
79
     * Instance of role service.
80
     *
81
     * @var \eZ\Publish\API\Repository\RoleService
82
     */
83
    protected $roleService;
84
85
    /**
86
     * Instance of search service.
87
     *
88
     * @var \eZ\Publish\API\Repository\SearchService
89
     */
90
    protected $searchService;
91
92
    /**
93
     * Instance of user service.
94
     *
95
     * @var \eZ\Publish\API\Repository\UserService
96
     */
97
    protected $userService;
98
99
    /**
100
     * Instance of language service.
101
     *
102
     * @var \eZ\Publish\API\Repository\LanguageService
103
     */
104
    protected $languageService;
105
106
    /**
107
     * Instance of location service.
108
     *
109
     * @var \eZ\Publish\API\Repository\LocationService
110
     */
111
    protected $locationService;
112
113
    /**
114
     * Instance of Trash service.
115
     *
116
     * @var \eZ\Publish\API\Repository\TrashService
117
     */
118
    protected $trashService;
119
120
    /**
121
     * Instance of content type service.
122
     *
123
     * @var \eZ\Publish\API\Repository\ContentTypeService
124
     */
125
    protected $contentTypeService;
126
127
    /**
128
     * Instance of object state service.
129
     *
130
     * @var \eZ\Publish\API\Repository\ObjectStateService
131
     */
132
    protected $objectStateService;
133
134
    /**
135
     * Instance of field type service.
136
     *
137
     * @var \eZ\Publish\API\Repository\FieldTypeService
138
     */
139
    protected $fieldTypeService;
140
141
    /**
142
     * Instance of FieldTypeRegistry.
143
     *
144
     * @var \eZ\Publish\Core\Repository\Helper\FieldTypeRegistry
145
     */
146
    private $fieldTypeRegistry;
147
148
    /**
149
     * Instance of NameableFieldTypeRegistry.
150
     *
151
     * @var \eZ\Publish\Core\Repository\Helper\NameableFieldTypeRegistry
152
     */
153
    private $nameableFieldTypeRegistry;
154
155
    /**
156
     * Instance of name schema resolver service.
157
     *
158
     * @var \eZ\Publish\Core\Repository\Helper\NameSchemaService
159
     */
160
    protected $nameSchemaService;
161
162
    /**
163
     * Instance of relation processor service.
164
     *
165
     * @var \eZ\Publish\Core\Repository\Helper\RelationProcessor
166
     */
167
    protected $relationProcessor;
168
169
    /**
170
     * Instance of URL alias service.
171
     *
172
     * @var \eZ\Publish\Core\Repository\URLAliasService
173
     */
174
    protected $urlAliasService;
175
176
    /**
177
     * Instance of URL wildcard service.
178
     *
179
     * @var \eZ\Publish\Core\Repository\URLWildcardService
180
     */
181
    protected $urlWildcardService;
182
183
    /**
184
     * Instance of URL service.
185
     *
186
     * @var \eZ\Publish\Core\Repository\URLService
187
     */
188
    protected $urlService;
189
190
    /**
191
     * Service settings, first level key is service name.
192
     *
193
     * @var array
194
     */
195
    protected $serviceSettings;
196
197
    /**
198
     * Instance of role service.
199
     *
200
     * @var \eZ\Publish\Core\Repository\Helper\LimitationService
201
     */
202
    protected $limitationService;
203
204
    /**
205
     * @var \eZ\Publish\Core\Repository\Helper\RoleDomainMapper
206
     */
207
    protected $roleDomainMapper;
208
209
    /**
210
     * Instance of domain mapper.
211
     *
212
     * @var \eZ\Publish\Core\Repository\Helper\DomainMapper
213
     */
214
    protected $domainMapper;
215
216
    /**
217
     * Instance of content type domain mapper.
218
     *
219
     * @var \eZ\Publish\Core\Repository\Helper\ContentTypeDomainMapper
220
     */
221
    protected $contentTypeDomainMapper;
222
223
    /**
224
     * Instance of permissions-resolver and -criterion resolver.
225
     *
226
     * @var \eZ\Publish\API\Repository\PermissionCriterionResolver|\eZ\Publish\API\Repository\PermissionResolver
227
     */
228
    protected $permissionsHandler;
229
230
    /**
231
     * @var \eZ\Publish\Core\Search\Common\BackgroundIndexer|null
232
     */
233
    protected $backgroundIndexer;
234
235
    /**
236
     * Array of arrays of commit events indexed by the transaction count.
237
     *
238
     * @var array
239
     */
240
    protected $commitEventsQueue = array();
241
242
    /**
243
     * @var int
244
     */
245
    protected $transactionDepth = 0;
246
247
    /**
248
     * @var int
249
     */
250
    private $transactionCount = 0;
251
252
    /**
253
     * @var \Psr\Log\LoggerInterface
254
     */
255
    private $logger;
256
257
    /**
258
     * Constructor.
259
     *
260
     * Construct repository object with provided storage engine
261
     *
262
     * @param \eZ\Publish\SPI\Persistence\Handler $persistenceHandler
263
     * @param \eZ\Publish\SPI\Search\Handler $searchHandler
264
     * @param \eZ\Publish\Core\Search\Common\BackgroundIndexer $backgroundIndexer
265
     * @param \eZ\Publish\Core\Repository\Helper\RelationProcessor $relationProcessor
266
     * @param array $serviceSettings
267
     * @param \eZ\Publish\API\Repository\Values\User\UserReference|null $user
268
     * @param \Psr\Log\LoggerInterface|null $logger
269
     */
270
    public function __construct(
271
        PersistenceHandler $persistenceHandler,
272
        SearchHandler $searchHandler,
273
        BackgroundIndexer $backgroundIndexer,
274
        RelationProcessor $relationProcessor,
275
        array $serviceSettings = array(),
276
        APIUserReference $user = null,
277
        LoggerInterface $logger = null
278
    ) {
279
        $this->persistenceHandler = $persistenceHandler;
280
        $this->searchHandler = $searchHandler;
281
        $this->backgroundIndexer = $backgroundIndexer;
282
        $this->relationProcessor = $relationProcessor;
283
        $this->serviceSettings = $serviceSettings + array(
284
            'content' => array(),
285
            'contentType' => array(),
286
            'location' => array(),
287
            'section' => array(),
288
            'role' => array(),
289
            'user' => array(
290
                'anonymousUserID' => 10,
291
            ),
292
            'language' => array(),
293
            'trash' => array(),
294
            'io' => array(),
295
            'objectState' => array(),
296
            'search' => array(),
297
            'fieldType' => array(),
298
            'nameableFieldTypes' => array(),
299
            'urlAlias' => array(),
300
            'urlWildcard' => array(),
301
            'nameSchema' => array(),
302
            'languages' => array(),
303
        );
304
305
        if (!empty($this->serviceSettings['languages'])) {
306
            $this->serviceSettings['language']['languages'] = $this->serviceSettings['languages'];
307
        }
308
309
        if ($user instanceof User) {
310
            $this->currentUser = $user;
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...epository::$currentUser has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user object if already loaded.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
311
            $this->currentUserRef = new UserReference($user->getUserId());
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...sitory::$currentUserRef has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user reference for permission purposes.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
312
        } elseif ($user instanceof APIUserReference) {
313
            $this->currentUserRef = $user;
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...sitory::$currentUserRef has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user reference for permission purposes.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
314
        } else {
315
            $this->currentUserRef = new UserReference($this->serviceSettings['user']['anonymousUserID']);
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...sitory::$currentUserRef has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user reference for permission purposes.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
316
        }
317
318
        $this->logger = null !== $logger ? $logger : new NullLogger();
319
    }
320
321
    /**
322
     * @deprecated since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead.
323
     *
324
     * Get current user.
325
     *
326
     * Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}
327
     *
328
     * @return \eZ\Publish\API\Repository\Values\User\User
329
     */
330
    public function getCurrentUser()
331
    {
332
        if ($this->currentUser === null) {
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...epository::$currentUser has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user object if already loaded.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
333
            $this->currentUser = $this->getUserService()->loadUser(
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...epository::$currentUser has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user object if already loaded.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
334
                $this->getPermissionResolver()->getCurrentUserReference()->getUserId()
335
            );
336
        }
337
338
        return $this->currentUser;
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...epository::$currentUser has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user object if already loaded.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
339
    }
340
341
    /**
342
     * @deprecated since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead.
343
     *
344
     * Get current user reference.
345
     *
346
     * @since 5.4.5
347
     * @return \eZ\Publish\API\Repository\Values\User\UserReference
348
     */
349
    public function getCurrentUserReference()
350
    {
351
        return $this->getPermissionResolver()->getCurrentUserReference();
352
    }
353
354
    /**
355
     * @deprecated since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead.
356
     *
357
     * Sets the current user to the given $user.
358
     *
359
     * @param \eZ\Publish\API\Repository\Values\User\UserReference $user
360
     *
361
     * @throws InvalidArgumentValue If UserReference does not contain a id
362
     */
363
    public function setCurrentUser(APIUserReference $user)
364
    {
365
        $id = $user->getUserId();
366
        if (!$id) {
367
            throw new InvalidArgumentValue('$user->getUserId()', $id);
368
        }
369
370
        if ($user instanceof User) {
371
            $this->currentUser = $user;
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...epository::$currentUser has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user object if already loaded.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
372
            $this->currentUserRef = new UserReference($id);
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...sitory::$currentUserRef has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user reference for permission purposes.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
373
        } else {
374
            $this->currentUser = null;
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...epository::$currentUser has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user object if already loaded.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
375
            $this->currentUserRef = $user;
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...sitory::$currentUserRef has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user reference for permission purposes.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
376
        }
377
378
        return $this->getPermissionResolver()->setCurrentUserReference($this->currentUserRef);
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...sitory::$currentUserRef has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user reference for permission purposes.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
379
    }
380
381
    /**
382
     * Allows API execution to be performed with full access sand-boxed.
383
     *
384
     * The closure sandbox will do a catch all on exceptions and rethrow after
385
     * re-setting the sudo flag.
386
     *
387
     * Example use:
388
     *     $location = $repository->sudo(
389
     *         function ( Repository $repo ) use ( $locationId )
390
     *         {
391
     *             return $repo->getLocationService()->loadLocation( $locationId )
392
     *         }
393
     *     );
394
     *
395
     *
396
     * @param \Closure $callback
397
     * @param \eZ\Publish\API\Repository\Repository $outerRepository
398
     *
399
     * @throws \RuntimeException Thrown on recursive sudo() use.
400
     * @throws \Exception Re throws exceptions thrown inside $callback
401
     *
402
     * @return mixed
403
     */
404
    public function sudo(\Closure $callback, RepositoryInterface $outerRepository = null)
405
    {
406
        return $this->getPermissionResolver()->sudo(
407
            $callback,
408
            $outerRepository !== null ? $outerRepository : $this
409
        );
410
    }
411
412
    /**
413
     * @deprecated since 6.6, to be removed. Use PermissionResolver::hasAccess() instead.
414
     *
415
     * Check if user has access to a given module / function.
416
     *
417
     * Low level function, use canUser instead if you have objects to check against.
418
     *
419
     * @param string $module
420
     * @param string $function
421
     * @param \eZ\Publish\API\Repository\Values\User\UserReference $user
422
     *
423
     * @return bool|array Bool if user has full or no access, array if limitations if not
424
     */
425
    public function hasAccess($module, $function, APIUserReference $user = null)
426
    {
427
        return $this->getPermissionResolver()->hasAccess($module, $function, $user);
428
    }
429
430
    /**
431
     * @deprecated since 6.6, to be removed. Use PermissionResolver::canUser() instead.
432
     *
433
     * Check if user has access to a given action on a given value object.
434
     *
435
     * Indicates if the current user is allowed to perform an action given by the function on the given
436
     * objects.
437
     *
438
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If any of the arguments are invalid
439
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException If value of the LimitationValue is unsupported
440
     *
441
     * @param string $module The module, aka controller identifier to check permissions on
442
     * @param string $function The function, aka the controller action to check permissions on
443
     * @param \eZ\Publish\API\Repository\Values\ValueObject $object The object to check if the user has access to
444
     * @param mixed $targets The location, parent or "assignment" value object, or an array of the same
445
     *
446
     * @return bool
447
     */
448
    public function canUser($module, $function, ValueObject $object, $targets = null)
449
    {
450
        if ($targets instanceof ValueObject) {
451
            $targets = array($targets);
452
        } elseif ($targets === null) {
453
            $targets = [];
454
        } elseif (!is_array($targets)) {
455
            throw new InvalidArgumentType(
456
                '$targets',
457
                'null|\\eZ\\Publish\\API\\Repository\\Values\\ValueObject|\\eZ\\Publish\\API\\Repository\\Values\\ValueObject[]',
458
                $targets
459
            );
460
        }
461
462
        return $this->getPermissionResolver()->canUser($module, $function, $object, $targets);
463
    }
464
465
    /**
466
     * Get Content Service.
467
     *
468
     * Get service object to perform operations on Content objects and it's aggregate members.
469
     *
470
     * @return \eZ\Publish\API\Repository\ContentService
471
     */
472 View Code Duplication
    public function getContentService()
473
    {
474
        if ($this->contentService !== null) {
475
            return $this->contentService;
476
        }
477
478
        $this->contentService = new ContentService(
479
            $this,
480
            $this->persistenceHandler,
481
            $this->getDomainMapper(),
482
            $this->getRelationProcessor(),
483
            $this->getNameSchemaService(),
484
            $this->getFieldTypeRegistry(),
485
            $this->serviceSettings['content']
486
        );
487
488
        return $this->contentService;
489
    }
490
491
    /**
492
     * Get Content Language Service.
493
     *
494
     * Get service object to perform operations on Content language objects
495
     *
496
     * @return \eZ\Publish\API\Repository\LanguageService
497
     */
498
    public function getContentLanguageService()
499
    {
500
        if ($this->languageService !== null) {
501
            return $this->languageService;
502
        }
503
504
        $this->languageService = new LanguageService(
505
            $this,
506
            $this->persistenceHandler->contentLanguageHandler(),
507
            $this->serviceSettings['language']
508
        );
509
510
        return $this->languageService;
511
    }
512
513
    /**
514
     * Get Content Type Service.
515
     *
516
     * Get service object to perform operations on Content Type objects and it's aggregate members.
517
     * ( Group, Field & FieldCategory )
518
     *
519
     * @return \eZ\Publish\API\Repository\ContentTypeService
520
     */
521 View Code Duplication
    public function getContentTypeService()
522
    {
523
        if ($this->contentTypeService !== null) {
524
            return $this->contentTypeService;
525
        }
526
527
        $this->contentTypeService = new ContentTypeService(
528
            $this,
529
            $this->persistenceHandler->contentTypeHandler(),
530
            $this->getDomainMapper(),
531
            $this->getContentTypeDomainMapper(),
532
            $this->getFieldTypeRegistry(),
533
            $this->serviceSettings['contentType']
534
        );
535
536
        return $this->contentTypeService;
537
    }
538
539
    /**
540
     * Get Content Location Service.
541
     *
542
     * Get service object to perform operations on Location objects and subtrees
543
     *
544
     * @return \eZ\Publish\API\Repository\LocationService
545
     */
546
    public function getLocationService()
547
    {
548
        if ($this->locationService !== null) {
549
            return $this->locationService;
550
        }
551
552
        $this->locationService = new LocationService(
553
            $this,
554
            $this->persistenceHandler,
555
            $this->getDomainMapper(),
556
            $this->getNameSchemaService(),
557
            $this->getPermissionCriterionResolver(),
558
            $this->serviceSettings['location'],
559
            $this->logger
560
        );
561
562
        return $this->locationService;
563
    }
564
565
    /**
566
     * Get Content Trash service.
567
     *
568
     * Trash service allows to perform operations related to location trash
569
     * (trash/untrash, load/list from trash...)
570
     *
571
     * @return \eZ\Publish\API\Repository\TrashService
572
     */
573
    public function getTrashService()
574
    {
575
        if ($this->trashService !== null) {
576
            return $this->trashService;
577
        }
578
579
        $this->trashService = new TrashService(
580
            $this,
581
            $this->persistenceHandler,
582
            $this->getNameSchemaService(),
583
            $this->serviceSettings['trash']
584
        );
585
586
        return $this->trashService;
587
    }
588
589
    /**
590
     * Get Content Section Service.
591
     *
592
     * Get Section service that lets you manipulate section objects
593
     *
594
     * @return \eZ\Publish\API\Repository\SectionService
595
     */
596
    public function getSectionService()
597
    {
598
        if ($this->sectionService !== null) {
599
            return $this->sectionService;
600
        }
601
602
        $this->sectionService = new SectionService(
603
            $this,
604
            $this->persistenceHandler->sectionHandler(),
605
            $this->serviceSettings['section']
606
        );
607
608
        return $this->sectionService;
609
    }
610
611
    /**
612
     * Get User Service.
613
     *
614
     * Get service object to perform operations on Users and UserGroup
615
     *
616
     * @return \eZ\Publish\API\Repository\UserService
617
     */
618
    public function getUserService()
619
    {
620
        if ($this->userService !== null) {
621
            return $this->userService;
622
        }
623
624
        $this->userService = new UserService(
625
            $this,
626
            $this->persistenceHandler->userHandler(),
627
            $this->serviceSettings['user']
628
        );
629
630
        return $this->userService;
631
    }
632
633
    /**
634
     * Get URLAliasService.
635
     *
636
     * @return \eZ\Publish\API\Repository\URLAliasService
637
     */
638
    public function getURLAliasService()
639
    {
640
        if ($this->urlAliasService !== null) {
641
            return $this->urlAliasService;
642
        }
643
644
        $this->urlAliasService = new URLAliasService(
645
            $this,
646
            $this->persistenceHandler->urlAliasHandler(),
647
            $this->getNameSchemaService(),
648
            $this->serviceSettings['urlAlias']
649
        );
650
651
        return $this->urlAliasService;
652
    }
653
654
    /**
655
     * Get URLWildcardService.
656
     *
657
     * @return \eZ\Publish\API\Repository\URLWildcardService
658
     */
659
    public function getURLWildcardService()
660
    {
661
        if ($this->urlWildcardService !== null) {
662
            return $this->urlWildcardService;
663
        }
664
665
        $this->urlWildcardService = new URLWildcardService(
666
            $this,
667
            $this->persistenceHandler->urlWildcardHandler(),
668
            $this->serviceSettings['urlWildcard']
669
        );
670
671
        return $this->urlWildcardService;
672
    }
673
674
    /**
675
     * Get URLService.
676
     *
677
     * @return \eZ\Publish\API\Repository\URLService
678
     */
679
    public function getURLService()
680
    {
681
        if ($this->urlService !== null) {
682
            return $this->urlService;
683
        }
684
685
        $this->urlService = new URLService(
686
            $this,
687
            $this->persistenceHandler->urlHandler()
688
        );
689
690
        return $this->urlService;
691
    }
692
693
    /**
694
     * Get ObjectStateService.
695
     *
696
     * @return \eZ\Publish\API\Repository\ObjectStateService
697
     */
698
    public function getObjectStateService()
699
    {
700
        if ($this->objectStateService !== null) {
701
            return $this->objectStateService;
702
        }
703
704
        $this->objectStateService = new ObjectStateService(
705
            $this,
706
            $this->persistenceHandler->objectStateHandler(),
707
            $this->serviceSettings['objectState']
708
        );
709
710
        return $this->objectStateService;
711
    }
712
713
    /**
714
     * Get RoleService.
715
     *
716
     * @return \eZ\Publish\API\Repository\RoleService
717
     */
718
    public function getRoleService()
719
    {
720
        if ($this->roleService !== null) {
721
            return $this->roleService;
722
        }
723
724
        $this->roleService = new RoleService(
725
            $this,
726
            $this->persistenceHandler->userHandler(),
727
            $this->getLimitationService(),
728
            $this->getRoleDomainMapper(),
729
            $this->serviceSettings['role']
730
        );
731
732
        return $this->roleService;
733
    }
734
735
    /**
736
     * Get LimitationService.
737
     *
738
     * @return \eZ\Publish\Core\Repository\Helper\LimitationService
739
     */
740
    protected function getLimitationService()
741
    {
742
        if ($this->limitationService !== null) {
743
            return $this->limitationService;
744
        }
745
746
        $this->limitationService = new Helper\LimitationService($this->serviceSettings['role']);
747
748
        return $this->limitationService;
749
    }
750
751
    /**
752
     * Get RoleDomainMapper.
753
     *
754
     * @return \eZ\Publish\Core\Repository\Helper\RoleDomainMapper
755
     */
756
    protected function getRoleDomainMapper()
757
    {
758
        if ($this->roleDomainMapper !== null) {
759
            return $this->roleDomainMapper;
760
        }
761
762
        $this->roleDomainMapper = new Helper\RoleDomainMapper($this->getLimitationService());
763
764
        return $this->roleDomainMapper;
765
    }
766
767
    /**
768
     * Get SearchService.
769
     *
770
     * @return \eZ\Publish\API\Repository\SearchService
771
     */
772
    public function getSearchService()
773
    {
774
        if ($this->searchService !== null) {
775
            return $this->searchService;
776
        }
777
778
        $this->searchService = new SearchService(
779
            $this,
780
            $this->searchHandler,
781
            $this->getDomainMapper(),
782
            $this->getPermissionCriterionResolver(),
783
            $this->backgroundIndexer,
0 ignored issues
show
Bug introduced by
It seems like $this->backgroundIndexer can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
784
            $this->serviceSettings['search']
785
        );
786
787
        return $this->searchService;
788
    }
789
790
    /**
791
     * Get FieldTypeService.
792
     *
793
     * @return \eZ\Publish\API\Repository\FieldTypeService
794
     */
795
    public function getFieldTypeService()
796
    {
797
        if ($this->fieldTypeService !== null) {
798
            return $this->fieldTypeService;
799
        }
800
801
        $this->fieldTypeService = new FieldTypeService($this->getFieldTypeRegistry());
802
803
        return $this->fieldTypeService;
804
    }
805
806
    /**
807
     * Get PermissionResolver.
808
     *
809
     * @return \eZ\Publish\API\Repository\PermissionResolver
810
     */
811
    public function getPermissionResolver()
812
    {
813
        return $this->getCachedPermissionsResolver();
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getCachedPermissionsResolver(); of type eZ\Publish\API\Repositor...tory\PermissionResolver adds the type eZ\Publish\API\Repositor...issionCriterionResolver to the return on line 813 which is incompatible with the return type declared by the interface eZ\Publish\API\Repositor...::getPermissionResolver of type eZ\Publish\API\Repository\PermissionResolver.
Loading history...
814
    }
815
816
    /**
817
     * @return Helper\FieldTypeRegistry
818
     */
819
    protected function getFieldTypeRegistry()
820
    {
821
        if ($this->fieldTypeRegistry !== null) {
822
            return $this->fieldTypeRegistry;
823
        }
824
825
        $this->fieldTypeRegistry = new Helper\FieldTypeRegistry($this->serviceSettings['fieldType']);
826
827
        return $this->fieldTypeRegistry;
828
    }
829
830
    /**
831
     * @return Helper\NameableFieldTypeRegistry
832
     */
833
    protected function getNameableFieldTypeRegistry()
834
    {
835
        if ($this->nameableFieldTypeRegistry !== null) {
836
            return $this->nameableFieldTypeRegistry;
837
        }
838
839
        $this->nameableFieldTypeRegistry = new Helper\NameableFieldTypeRegistry($this->serviceSettings['nameableFieldTypes']);
840
841
        return $this->nameableFieldTypeRegistry;
842
    }
843
844
    /**
845
     * Get NameSchemaResolverService.
846
     *
847
     *
848
     * @todo Move out from this & other repo instances when services becomes proper services in DIC terms using factory.
849
     *
850
     * @internal
851
     * @private
852
     *
853
     * @return \eZ\Publish\Core\Repository\Helper\NameSchemaService
854
     */
855
    public function getNameSchemaService()
856
    {
857
        if ($this->nameSchemaService !== null) {
858
            return $this->nameSchemaService;
859
        }
860
861
        $this->nameSchemaService = new Helper\NameSchemaService(
862
            $this->persistenceHandler->contentTypeHandler(),
863
            $this->getContentTypeDomainMapper(),
864
            $this->getNameableFieldTypeRegistry(),
865
            $this->serviceSettings['nameSchema']
866
        );
867
868
        return $this->nameSchemaService;
869
    }
870
871
    /**
872
     * Get RelationProcessor.
873
     *
874
     *
875
     * @todo Move out from this & other repo instances when services becomes proper services in DIC terms using factory.
876
     *
877
     * @return \eZ\Publish\Core\Repository\Helper\RelationProcessor
878
     */
879
    protected function getRelationProcessor()
880
    {
881
        return $this->relationProcessor;
882
    }
883
884
    /**
885
     * Get Content Domain Mapper.
886
     *
887
     * @todo Move out from this & other repo instances when services becomes proper services in DIC terms using factory.
888
     *
889
     * @return \eZ\Publish\Core\Repository\Helper\DomainMapper
890
     */
891
    protected function getDomainMapper()
892
    {
893
        if ($this->domainMapper !== null) {
894
            return $this->domainMapper;
895
        }
896
897
        $this->domainMapper = new Helper\DomainMapper(
898
            $this->persistenceHandler->contentHandler(),
899
            $this->persistenceHandler->locationHandler(),
900
            $this->persistenceHandler->contentTypeHandler(),
901
            $this->persistenceHandler->contentLanguageHandler(),
902
            $this->getFieldTypeRegistry()
903
        );
904
905
        return $this->domainMapper;
906
    }
907
908
    /**
909
     * Get ContentType Domain Mapper.
910
     *
911
     * @todo Move out from this & other repo instances when services becomes proper services in DIC terms using factory.
912
     *
913
     * @return \eZ\Publish\Core\Repository\Helper\ContentTypeDomainMapper
914
     */
915
    protected function getContentTypeDomainMapper()
916
    {
917
        if ($this->contentTypeDomainMapper !== null) {
918
            return $this->contentTypeDomainMapper;
919
        }
920
921
        $this->contentTypeDomainMapper = new Helper\ContentTypeDomainMapper(
922
            $this->persistenceHandler->contentLanguageHandler(),
923
            $this->getFieldTypeRegistry()
924
        );
925
926
        return $this->contentTypeDomainMapper;
927
    }
928
929
    /**
930
     * Get PermissionCriterionResolver.
931
     *
932
     * @todo Move out from this & other repo instances when services becomes proper services in DIC terms using factory.
933
     *
934
     * @return \eZ\Publish\API\Repository\PermissionCriterionResolver
935
     */
936
    protected function getPermissionCriterionResolver()
937
    {
938
        return $this->getCachedPermissionsResolver();
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getCachedPermissionsResolver(); of type eZ\Publish\API\Repositor...tory\PermissionResolver adds the type eZ\Publish\API\Repository\PermissionResolver to the return on line 938 which is incompatible with the return type documented by eZ\Publish\Core\Reposito...issionCriterionResolver of type eZ\Publish\API\Repositor...issionCriterionResolver.
Loading history...
939
    }
940
941
    /**
942
     * @return \eZ\Publish\API\Repository\PermissionCriterionResolver|\eZ\Publish\API\Repository\PermissionResolver
943
     */
944
    protected function getCachedPermissionsResolver()
945
    {
946
        if ($this->permissionsHandler === null) {
947
            $this->permissionsHandler = new CachedPermissionService(
948
                $permissionResolver = new Permission\PermissionResolver(
949
                    $this->getRoleDomainMapper(),
950
                    $this->getLimitationService(),
951
                    $this->persistenceHandler->userHandler(),
952
                    $this->currentUserRef
0 ignored issues
show
Deprecated Code introduced by
The property eZ\Publish\Core\Reposito...sitory::$currentUserRef has been deprecated with message: since 6.6, to be removed. Current user handling is moved to PermissionResolver. Currently logged in user reference for permission purposes.

This property 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 property will be removed from the class and what other property to use instead.

Loading history...
953
                ),
954
                new PermissionCriterionResolver(
955
                    $permissionResolver,
956
                    $this->getLimitationService()
957
                )
958
            );
959
        }
960
961
        return $this->permissionsHandler;
962
    }
963
964
    /**
965
     * Begin transaction.
966
     *
967
     * Begins an transaction, make sure you'll call commit or rollback when done,
968
     * otherwise work will be lost.
969
     */
970
    public function beginTransaction()
971
    {
972
        $this->persistenceHandler->beginTransaction();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\SPI\Persisten...ler::beginTransaction() has been deprecated with message: Since 5.3 {@use transactionHandler()->beginTransaction()}

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...
973
974
        ++$this->transactionDepth;
975
        $this->commitEventsQueue[++$this->transactionCount] = array();
976
    }
977
978
    /**
979
     * Commit transaction.
980
     *
981
     * Commit transaction, or throw exceptions if no transactions has been started.
982
     *
983
     * @throws RuntimeException If no transaction has been started
984
     */
985
    public function commit()
986
    {
987
        try {
988
            $this->persistenceHandler->commit();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\SPI\Persistence\Handler::commit() has been deprecated with message: Since 5.3 {@use transactionHandler()->commit()}

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...
989
990
            --$this->transactionDepth;
991
992
            if ($this->transactionDepth === 0) {
993
                $queueCountDown = count($this->commitEventsQueue);
994
                foreach ($this->commitEventsQueue as $eventsQueue) {
995
                    --$queueCountDown;
996
                    if (empty($eventsQueue)) {
997
                        continue;
998
                    }
999
1000
                    $eventCountDown = count($eventsQueue);
1001
                    foreach ($eventsQueue as $event) {
1002
                        --$eventCountDown;
1003
                        // event expects a boolean param, if true it means it is last event (for commit use)
1004
                        $event($queueCountDown === 0 && $eventCountDown === 0);
1005
                    }
1006
                }
1007
1008
                $this->commitEventsQueue = array();
1009
            }
1010
        } catch (Exception $e) {
1011
            throw new RuntimeException($e->getMessage(), 0, $e);
1012
        }
1013
    }
1014
1015
    /**
1016
     * Rollback transaction.
1017
     *
1018
     * Rollback transaction, or throw exceptions if no transactions has been started.
1019
     *
1020
     * @throws RuntimeException If no transaction has been started
1021
     */
1022
    public function rollback()
1023
    {
1024
        try {
1025
            $this->persistenceHandler->rollback();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\SPI\Persistence\Handler::rollback() has been deprecated with message: Since 5.3 {@use transactionHandler()->rollback()}

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...
1026
1027
            --$this->transactionDepth;
1028
            unset($this->commitEventsQueue[$this->transactionCount]);
1029
        } catch (Exception $e) {
1030
            throw new RuntimeException($e->getMessage(), 0, $e);
1031
        }
1032
    }
1033
1034
    /**
1035
     * Enqueue an event to be triggered at commit or directly if no transaction has started.
1036
     *
1037
     * @param callable $event
1038
     */
1039
    public function commitEvent($event)
1040
    {
1041
        if ($this->transactionDepth !== 0) {
1042
            $this->commitEventsQueue[$this->transactionCount][] = $event;
1043
        } else {
1044
            // event expects a boolean param, if true it means it is last event (for commit use)
1045
            $event(true);
1046
        }
1047
    }
1048
1049
    /**
1050
     * Only for internal use.
1051
     *
1052
     * Creates a \DateTime object for $timestamp in the current time zone
1053
     *
1054
     * @param int $timestamp
1055
     *
1056
     * @return \DateTime
1057
     */
1058 View Code Duplication
    public function createDateTime($timestamp = null)
1059
    {
1060
        $dateTime = new \DateTime();
1061
        if ($timestamp !== null) {
1062
            $dateTime->setTimestamp($timestamp);
1063
        }
1064
1065
        return $dateTime;
1066
    }
1067
}
1068