Completed
Push — siteaccessaware-layer-only ( 14ffb6 )
by André
15:43
created

Repository::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 29

Duplication

Lines 31
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 29
nc 1
nop 14
dl 31
loc 31
rs 8.8571
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * Repository 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\SiteAccessAware;
10
11
use eZ\Publish\API\Repository\Repository as RepositoryInterface;
12
use eZ\Publish\API\Repository\Values\ValueObject;
13
use eZ\Publish\API\Repository\Values\User\UserReference;
14
15
/**
16
 * Repository class.
17
 */
18
class Repository implements RepositoryInterface
19
{
20
    /**
21
     * Repository Handler object.
22
     *
23
     * @var \eZ\Publish\API\Repository\Repository
24
     */
25
    protected $repository;
26
27
    /**
28
     * Instance of content service.
29
     *
30
     * @var \eZ\Publish\API\Repository\ContentService
31
     */
32
    protected $contentService;
33
34
    /**
35
     * Instance of section service.
36
     *
37
     * @var \eZ\Publish\API\Repository\SectionService
38
     */
39
    protected $sectionService;
40
41
    /**
42
     * Instance of role service.
43
     *
44
     * @var \eZ\Publish\API\Repository\RoleService
45
     */
46
    protected $roleService;
47
48
    /**
49
     * Instance of search service.
50
     *
51
     * @var \eZ\Publish\API\Repository\SearchService
52
     */
53
    protected $searchService;
54
55
    /**
56
     * Instance of user service.
57
     *
58
     * @var \eZ\Publish\API\Repository\UserService
59
     */
60
    protected $userService;
61
62
    /**
63
     * Instance of language service.
64
     *
65
     * @var \eZ\Publish\API\Repository\LanguageService
66
     */
67
    protected $languageService;
68
69
    /**
70
     * Instance of location service.
71
     *
72
     * @var \eZ\Publish\API\Repository\LocationService
73
     */
74
    protected $locationService;
75
76
    /**
77
     * Instance of Trash service.
78
     *
79
     * @var \eZ\Publish\API\Repository\TrashService
80
     */
81
    protected $trashService;
82
83
    /**
84
     * Instance of content type service.
85
     *
86
     * @var \eZ\Publish\API\Repository\ContentTypeService
87
     */
88
    protected $contentTypeService;
89
90
    /**
91
     * Instance of object state service.
92
     *
93
     * @var \eZ\Publish\API\Repository\ObjectStateService
94
     */
95
    protected $objectStateService;
96
97
    /**
98
     * Instance of field type service.
99
     *
100
     * @var \eZ\Publish\API\Repository\FieldTypeService
101
     */
102
    protected $fieldTypeService;
103
104
    /**
105
     * Instance of URL alias service.
106
     *
107
     * @var \eZ\Publish\Core\Repository\URLAliasService
108
     */
109
    protected $urlAliasService;
110
111
    /**
112
     * Instance of URL wildcard service.
113
     *
114
     * @var \eZ\Publish\Core\Repository\URLWildcardService
115
     */
116
    protected $urlWildcardService;
117
118
    /**
119
     * Constructor.
120
     *
121
     * Construct repository object from aggregated repository
122
     *
123
     * @param \eZ\Publish\API\Repository\Repository $repository
124
     * @param ContentService $contentService
125
     * @param ContentTypeService $contentTypeService
126
     * @param FieldTypeService $fieldTypeService
127
     * @param RoleService $roleService
128
     * @param ObjectStateService $objectStateService
129
     * @param URLWildcardService $urlWildcardService
130
     * @param URLAliasService $urlAliasService
131
     * @param UserService $userService
132
     * @param SearchService $searchService
133
     * @param SectionService $sectionService
134
     * @param TrashService $trashService
135
     * @param LocationService $locationService
136
     * @param LanguageService $languageService
137
     */
138 View Code Duplication
    public function __construct(
139
        RepositoryInterface $repository,
140
        ContentService $contentService,
141
        ContentTypeService $contentTypeService,
142
        FieldTypeService $fieldTypeService,
143
        RoleService $roleService,
144
        ObjectStateService $objectStateService,
145
        URLWildcardService $urlWildcardService,
146
        URLAliasService $urlAliasService,
147
        UserService $userService,
148
        SearchService $searchService,
149
        SectionService $sectionService,
150
        TrashService $trashService,
151
        LocationService $locationService,
152
        LanguageService $languageService
153
    ) {
154
        $this->repository = $repository;
155
        $this->contentService = $contentService;
156
        $this->contentTypeService = $contentTypeService;
157
        $this->fieldTypeService = $fieldTypeService;
158
        $this->roleService = $roleService;
159
        $this->objectStateService = $objectStateService;
160
        $this->urlWildcardService = $urlWildcardService;
0 ignored issues
show
Documentation Bug introduced by
It seems like $urlWildcardService of type object<eZ\Publish\Core\R...are\URLWildcardService> is incompatible with the declared type object<eZ\Publish\Core\R...ory\URLWildcardService> of property $urlWildcardService.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
161
        $this->urlAliasService = $urlAliasService;
0 ignored issues
show
Documentation Bug introduced by
It seems like $urlAliasService of type object<eZ\Publish\Core\R...sAware\URLAliasService> is incompatible with the declared type object<eZ\Publish\Core\R...sitory\URLAliasService> of property $urlAliasService.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
162
        $this->userService = $userService;
163
        $this->searchService = $searchService;
164
        $this->sectionService = $sectionService;
165
        $this->trashService = $trashService;
166
        $this->locationService = $locationService;
167
        $this->languageService = $languageService;
168
    }
169
170
    /**
171
     * @deprecated since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead.
172
     *
173
     * Get current user.
174
     *
175
     * @return \eZ\Publish\API\Repository\Values\User\User
176
     */
177
    public function getCurrentUser()
178
    {
179
        return $this->repository->getCurrentUser();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

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...
180
    }
181
182
    /**
183
     * @deprecated since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead.
184
     *
185
     * Get current user ref.
186
     *
187
     * @return \eZ\Publish\API\Repository\Values\User\UserReference
188
     */
189
    public function getCurrentUserReference()
190
    {
191
        return $this->repository->getCurrentUserReference();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...tCurrentUserReference() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user reference.

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...
192
    }
193
194
    /**
195
     * @deprecated since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead.
196
     *
197
     * Sets the current user to the given $user.
198
     *
199
     * @param \eZ\Publish\API\Repository\Values\User\UserReference $user
200
     */
201
    public function setCurrentUser(UserReference $user)
202
    {
203
        return $this->repository->setCurrentUser($user);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::setCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead. Sets the current user to the given $user.

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...
204
    }
205
206
    /**
207
     * Allows API execution to be performed with full access sand-boxed.
208
     *
209
     * The closure sandbox will do a catch all on exceptions and rethrow after
210
     * re-setting the sudo flag.
211
     *
212
     * Example use:
213
     *     $location = $repository->sudo(
214
     *         function ( Repository $repo ) use ( $locationId )
215
     *         {
216
     *             return $repo->getLocationService()->loadLocation( $locationId )
217
     *         }
218
     *     );
219
     *
220
     *
221
     * @param \Closure $callback
222
     *
223
     * @throws \RuntimeException Thrown on recursive sudo() use.
224
     * @throws \Exception Re throws exceptions thrown inside $callback
225
     *
226
     * @return mixed
227
     */
228
    public function sudo(\Closure $callback)
229
    {
230
        return $this->repository->sudo($callback, $this);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface eZ\Publish\API\Repository\Repository as the method sudo() does only exist in the following implementations of said interface: eZ\Publish\Core\Repository\Repository, eZ\Publish\Core\Reposito...eAccessAware\Repository, eZ\Publish\Core\SignalSlot\Repository.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
231
    }
232
233
    /**
234
     * @deprecated since 6.6, to be removed. Use PermissionResolver::hasAccess() instead.
235
     *
236
     * Check if user has access to a given module / function.
237
     *
238
     * Low level function, use canUser instead if you have objects to check against.
239
     *
240
     * @param string $module
241
     * @param string $function
242
     * @param \eZ\Publish\API\Repository\Values\User\UserReference $user
243
     *
244
     * @return bool|array Bool if user has full or no access, array if limitations if not
245
     */
246
    public function hasAccess($module, $function, UserReference $user = null)
247
    {
248
        return $this->repository->hasAccess($module, $function, $user);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() instead.

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...
249
    }
250
251
    /**
252
     * @deprecated since 6.6, to be removed. Use PermissionResolver::canUser() instead.
253
     *
254
     * Check if user has access to a given action on a given value object.
255
     *
256
     * Indicates if the current user is allowed to perform an action given by the function on the given
257
     * objects.
258
     *
259
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If any of the arguments are invalid
260
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException If value of the LimitationValue is unsupported
261
     *
262
     * @param string $module The module, aka controller identifier to check permissions on
263
     * @param string $function The function, aka the controller action to check permissions on
264
     * @param \eZ\Publish\API\Repository\Values\ValueObject $object The object to check if the user has access to
265
     * @param mixed $targets The location, parent or "assignment" value object, or an array of the same
266
     *
267
     * @return bool
268
     */
269
    public function canUser($module, $function, ValueObject $object, $targets = null)
270
    {
271
        return $this->repository->canUser($module, $function, $object, $targets);
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...
272
    }
273
274
    /**
275
     * Get Content Service.
276
     *
277
     * Get service object to perform operations on Content objects and it's aggregate members.
278
     *
279
     * @return \eZ\Publish\API\Repository\ContentService
280
     */
281
    public function getContentService()
282
    {
283
        return $this->contentService;
284
    }
285
286
    /**
287
     * Get Content Language Service.
288
     *
289
     * Get service object to perform operations on Content language objects
290
     *
291
     * @return \eZ\Publish\API\Repository\LanguageService
292
     */
293
    public function getContentLanguageService()
294
    {
295
        return $this->languageService;
296
    }
297
298
    /**
299
     * Get Content Type Service.
300
     *
301
     * Get service object to perform operations on Content Type objects and it's aggregate members.
302
     * ( Group, Field & FieldCategory )
303
     *
304
     * @return \eZ\Publish\API\Repository\ContentTypeService
305
     */
306
    public function getContentTypeService()
307
    {
308
        return $this->contentTypeService;
309
    }
310
311
    /**
312
     * Get Content Location Service.
313
     *
314
     * Get service object to perform operations on Location objects and subtrees
315
     *
316
     * @return \eZ\Publish\API\Repository\LocationService
317
     */
318
    public function getLocationService()
319
    {
320
        return $this->locationService;
321
    }
322
323
    /**
324
     * Get Content Trash service.
325
     *
326
     * Trash service allows to perform operations related to location trash
327
     * (trash/untrash, load/list from trash...)
328
     *
329
     * @return \eZ\Publish\API\Repository\TrashService
330
     */
331
    public function getTrashService()
332
    {
333
        return $this->trashService;
334
    }
335
336
    /**
337
     * Get Content Section Service.
338
     *
339
     * Get Section service that lets you manipulate section objects
340
     *
341
     * @return \eZ\Publish\API\Repository\SectionService
342
     */
343
    public function getSectionService()
344
    {
345
        return $this->sectionService;
346
    }
347
348
    /**
349
     * Get User Service.
350
     *
351
     * Get service object to perform operations on Users and UserGroup
352
     *
353
     * @return \eZ\Publish\API\Repository\UserService
354
     */
355
    public function getUserService()
356
    {
357
        return $this->userService;
358
    }
359
360
    /**
361
     * Get URLAliasService.
362
     *
363
     * @return \eZ\Publish\API\Repository\URLAliasService
364
     */
365
    public function getURLAliasService()
366
    {
367
        return $this->urlAliasService;
368
    }
369
370
    /**
371
     * Get URLWildcardService.
372
     *
373
     * @return \eZ\Publish\API\Repository\URLWildcardService
374
     */
375
    public function getURLWildcardService()
376
    {
377
        return $this->urlWildcardService;
378
    }
379
380
    /**
381
     * Get ObjectStateService.
382
     *
383
     * @return \eZ\Publish\API\Repository\ObjectStateService
384
     */
385
    public function getObjectStateService()
386
    {
387
        return $this->objectStateService;
388
    }
389
390
    /**
391
     * Get RoleService.
392
     *
393
     * @return \eZ\Publish\API\Repository\RoleService
394
     */
395
    public function getRoleService()
396
    {
397
        return $this->roleService;
398
    }
399
400
    /**
401
     * Get SearchService.
402
     *
403
     * @return \eZ\Publish\API\Repository\SearchService
404
     */
405
    public function getSearchService()
406
    {
407
        return $this->searchService;
408
    }
409
410
    /**
411
     * Get FieldTypeService.
412
     *
413
     * @return \eZ\Publish\API\Repository\FieldTypeService
414
     */
415
    public function getFieldTypeService()
416
    {
417
        return $this->fieldTypeService;
418
    }
419
420
    /**
421
     * Get PermissionResolver.
422
     *
423
     * @return \eZ\Publish\API\Repository\PermissionResolver
424
     */
425
    public function getPermissionResolver()
426
    {
427
        return $this->repository->getPermissionResolver();
428
    }
429
430
    /**
431
     * Begin transaction.
432
     *
433
     * Begins an transaction, make sure you'll call commit or rollback when done,
434
     * otherwise work will be lost.
435
     */
436
    public function beginTransaction()
437
    {
438
        return $this->repository->beginTransaction();
439
    }
440
441
    /**
442
     * Commit transaction.
443
     *
444
     * Commit transaction, or throw exceptions if no transactions has been started.
445
     *
446
     * @throws \RuntimeException If no transaction has been started
447
     */
448
    public function commit()
449
    {
450
        return $this->repository->commit();
451
    }
452
453
    /**
454
     * Rollback transaction.
455
     *
456
     * Rollback transaction, or throw exceptions if no transactions has been started.
457
     *
458
     * @throws \RuntimeException If no transaction has been started
459
     */
460
    public function rollback()
461
    {
462
        return $this->repository->rollback();
463
    }
464
465
    /**
466
     * Enqueue an event to be triggered at commit or directly if no transaction has started.
467
     *
468
     * @deprecated In 5.3.3, to be removed. Signals are emitted after transaction instead of being required to use this.
469
     *
470
     * @param Callable $event
471
     */
472
    public function commitEvent($event)
473
    {
474
        return $this->repository->commitEvent($event);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...pository::commitEvent() has been deprecated with message: In 5.3.3, to be removed. Signals are emitted after transaction instead of being required to use this.

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...
475
    }
476
477
    /**
478
     * Only for internal use.
479
     *
480
     * Creates a \DateTime object for $timestamp in the current time zone
481
     *
482
     * @param int $timestamp
483
     *
484
     * @return \DateTime
485
     */
486
    public function createDateTime($timestamp = null)
487
    {
488
        return $this->repository->createDateTime($timestamp);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface eZ\Publish\API\Repository\Repository as the method createDateTime() does only exist in the following implementations of said interface: eZ\Publish\Core\Repository\Repository, eZ\Publish\Core\Reposito...eAccessAware\Repository, eZ\Publish\Core\SignalSlot\Repository.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
489
    }
490
}
491