Completed
Push — EZP-31383 ( 83ce0c )
by
unknown
19:12
created

DoctrineDatabase::copyRole()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 29

Duplication

Lines 5
Ratio 17.24 %

Importance

Changes 0
Metric Value
dl 5
loc 29
c 0
b 0
f 0
cc 4
nc 2
nop 1
rs 9.456
1
<?php
2
3
/**
4
 * File containing the DoctrineDatabase User Role Gateway 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\Persistence\Legacy\User\Role\Gateway;
10
11
use eZ\Publish\Core\Persistence\Legacy\User\Role\Gateway;
12
use eZ\Publish\Core\Persistence\Database\DatabaseHandler;
13
use eZ\Publish\SPI\Persistence\User\Policy;
14
use eZ\Publish\SPI\Persistence\User\RoleUpdateStruct;
15
use eZ\Publish\SPI\Persistence\User\Role;
16
17
/**
18
 * User Role gateway implementation using the Doctrine database.
19
 */
20
class DoctrineDatabase extends Gateway
21
{
22
    /**
23
     * Database handler.
24
     *
25
     * @var \eZ\Publish\Core\Persistence\Database\DatabaseHandler
26
     */
27
    protected $handler;
28
29
    /**
30
     * Construct from database handler.
31
     *
32
     * @param \eZ\Publish\Core\Persistence\Database\DatabaseHandler $handler
33
     */
34
    public function __construct(DatabaseHandler $handler)
35
    {
36
        $this->handler = $handler;
37
    }
38
39
    /**
40
     * Create new role.
41
     *
42
     * @param \eZ\Publish\SPI\Persistence\User\Role $role
43
     *
44
     * @return Role
45
     */
46
    public function createRole(Role $role)
47
    {
48
        // Role original ID is set when creating a draft from an existing role
49
        if ($role->status === Role::STATUS_DRAFT && $role->id) {
50
            $roleOriginalId = $role->id;
51
        } elseif ($role->status === Role::STATUS_DRAFT) {
52
            // Not using a constant here as this is legacy storage engine specific.
53
            // -1 means "Newly created role".
54
            $roleOriginalId = -1;
55
        } else {
56
            // Role::STATUS_DEFINED value is 0, which is the expected value for version column for this status.
57
            $roleOriginalId = Role::STATUS_DEFINED;
58
        }
59
60
        $query = $this->handler->createInsertQuery();
61
        $query
62
            ->insertInto($this->handler->quoteTable('ezrole'))
63
            ->set(
64
                $this->handler->quoteColumn('id'),
65
                $this->handler->getAutoIncrementValue('ezrole', 'id')
66
            )->set(
67
                $this->handler->quoteColumn('is_new'),
68
                0
69
            )->set(
70
                $this->handler->quoteColumn('name'),
71
                $query->bindValue($role->identifier)
72
            )->set(
73
                $this->handler->quoteColumn('value'),
74
                0
75
            )->set(
76
                // Column name "version" is misleading here as it stores originalId when creating a draft from an existing role.
77
                // But hey, this is legacy! :-)
78
                $this->handler->quoteColumn('version'),
79
                $query->bindValue($roleOriginalId)
80
            );
81
        $query->prepare()->execute();
82
83 View Code Duplication
        if (!isset($role->id) || (int)$role->id < 1 || $role->status === Role::STATUS_DRAFT) {
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...
84
            $role->id = $this->handler->lastInsertId(
85
                $this->handler->getSequenceName('ezrole', 'id')
86
            );
87
        }
88
89
        $role->originalId = $roleOriginalId;
90
    }
91
92
    /**
93
     * Copies an existing role.
94
     *
95
     * @param \eZ\Publish\SPI\Persistence\User\Role $role
96
     */
97
    public function copyRole(Role $role)
98
    {
99
        $query = $this->handler->createInsertQuery();
100
        $query
101
            ->insertInto($this->handler->quoteTable('ezrole'))
102
            ->set(
103
                $this->handler->quoteColumn('id'),
104
                $this->handler->getAutoIncrementValue('ezrole', 'id')
105
            )->set(
106
                $this->handler->quoteColumn('is_new'),
107
                0
108
            )->set(
109
                $this->handler->quoteColumn('name'),
110
                $query->bindValue($role->identifier)
111
            )->set(
112
                $this->handler->quoteColumn('value'),
113
                0
114
            )->set(
115
                $this->handler->quoteColumn('version'),
116
                $query->bindValue(0)
117
            );
118
        $query->prepare()->execute();
119
120 View Code Duplication
        if (!isset($role->id) || (int)$role->id < 1 || $role->status === Role::STATUS_DRAFT) {
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...
121
            $role->id = $this->handler->lastInsertId(
122
                $this->handler->getSequenceName('ezrole', 'id')
123
            );
124
        }
125
    }
126
127
    /**
128
     * Loads a specified role by id.
129
     *
130
     * @param mixed $roleId
131
     * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT
132
     *
133
     * @return array
134
     */
135 View Code Duplication
    public function loadRole($roleId, $status = Role::STATUS_DEFINED)
136
    {
137
        $query = $this->handler->createSelectQuery();
138
        if ($status === Role::STATUS_DEFINED) {
139
            $draftCondition = $query->expr->eq(
140
                $this->handler->quoteColumn('version', 'ezrole'),
141
                $query->bindValue($status, null, \PDO::PARAM_INT)
142
            );
143
        } else {
144
            $draftCondition = $query->expr->neq(
145
                $this->handler->quoteColumn('version', 'ezrole'),
146
                $query->bindValue(Role::STATUS_DEFINED, null, \PDO::PARAM_INT)
147
            );
148
        }
149
150
        $query->select(
151
            $this->handler->aliasedColumn($query, 'id', 'ezrole'),
152
            $this->handler->aliasedColumn($query, 'name', 'ezrole'),
153
            $this->handler->aliasedColumn($query, 'version', 'ezrole'),
154
            $this->handler->aliasedColumn($query, 'id', 'ezpolicy'),
155
            $this->handler->aliasedColumn($query, 'function_name', 'ezpolicy'),
156
            $this->handler->aliasedColumn($query, 'module_name', 'ezpolicy'),
157
            $this->handler->aliasedColumn($query, 'original_id', 'ezpolicy'),
158
            $this->handler->aliasedColumn($query, 'identifier', 'ezpolicy_limitation'),
159
            $this->handler->aliasedColumn($query, 'value', 'ezpolicy_limitation_value')
160
        )->from(
161
            $this->handler->quoteTable('ezrole')
162
        )->leftJoin(
163
            $this->handler->quoteTable('ezpolicy'),
164
            $query->expr->eq(
165
                $this->handler->quoteColumn('role_id', 'ezpolicy'),
166
                $this->handler->quoteColumn('id', 'ezrole')
167
            )
168
        )->leftJoin(
169
            $this->handler->quoteTable('ezpolicy_limitation'),
170
            $query->expr->eq(
171
                $this->handler->quoteColumn('policy_id', 'ezpolicy_limitation'),
172
                $this->handler->quoteColumn('id', 'ezpolicy')
173
            )
174
        )->leftJoin(
175
            $this->handler->quoteTable('ezpolicy_limitation_value'),
176
            $query->expr->eq(
177
                $this->handler->quoteColumn('limitation_id', 'ezpolicy_limitation_value'),
178
                $this->handler->quoteColumn('id', 'ezpolicy_limitation')
179
            )
180
        )->where(
181
            $query->expr->lAnd(
182
                $query->expr->eq(
183
                    $this->handler->quoteColumn('id', 'ezrole'),
184
                    $query->bindValue($roleId, null, \PDO::PARAM_INT)
185
                ),
186
                $draftCondition
187
            )
188
        );
189
190
        $statement = $query->prepare();
191
        $statement->execute();
192
193
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
194
    }
195
196
    /**
197
     * Loads a specified role by $identifier.
198
     *
199
     * @param string $identifier
200
     * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT
201
     *
202
     * @return array
203
     */
204 View Code Duplication
    public function loadRoleByIdentifier($identifier, $status = Role::STATUS_DEFINED)
205
    {
206
        $query = $this->handler->createSelectQuery();
207
        if ($status === Role::STATUS_DEFINED) {
208
            $roleVersionCondition = $query->expr->eq(
209
                $this->handler->quoteColumn('version', 'ezrole'),
210
                $query->bindValue($status, null, \PDO::PARAM_INT)
211
            );
212
        } else {
213
            $roleVersionCondition = $query->expr->neq(
214
                $this->handler->quoteColumn('version', 'ezrole'),
215
                $query->bindValue($status, null, \PDO::PARAM_INT)
216
            );
217
        }
218
219
        $query->select(
220
            $this->handler->aliasedColumn($query, 'id', 'ezrole'),
221
            $this->handler->aliasedColumn($query, 'name', 'ezrole'),
222
            $this->handler->aliasedColumn($query, 'version', 'ezrole'),
223
            $this->handler->aliasedColumn($query, 'id', 'ezpolicy'),
224
            $this->handler->aliasedColumn($query, 'function_name', 'ezpolicy'),
225
            $this->handler->aliasedColumn($query, 'module_name', 'ezpolicy'),
226
            $this->handler->aliasedColumn($query, 'original_id', 'ezpolicy'),
227
            $this->handler->aliasedColumn($query, 'identifier', 'ezpolicy_limitation'),
228
            $this->handler->aliasedColumn($query, 'value', 'ezpolicy_limitation_value')
229
        )->from(
230
            $this->handler->quoteTable('ezrole')
231
        )->leftJoin(
232
            $this->handler->quoteTable('ezpolicy'),
233
                $query->expr->eq(
234
                $this->handler->quoteColumn('role_id', 'ezpolicy'),
235
                $this->handler->quoteColumn('id', 'ezrole')
236
            )
237
        )->leftJoin(
238
            $this->handler->quoteTable('ezpolicy_limitation'),
239
            $query->expr->eq(
240
                $this->handler->quoteColumn('policy_id', 'ezpolicy_limitation'),
241
                $this->handler->quoteColumn('id', 'ezpolicy')
242
            )
243
        )->leftJoin(
244
            $this->handler->quoteTable('ezpolicy_limitation_value'),
245
            $query->expr->eq(
246
                $this->handler->quoteColumn('limitation_id', 'ezpolicy_limitation_value'),
247
                $this->handler->quoteColumn('id', 'ezpolicy_limitation')
248
            )
249
        )->where(
250
            $query->expr->lAnd(
251
                $query->expr->eq(
252
                    $this->handler->quoteColumn('name', 'ezrole'),
253
                    $query->bindValue($identifier, null, \PDO::PARAM_STR)
254
                ),
255
                $roleVersionCondition
256
            )
257
        );
258
259
        $statement = $query->prepare();
260
        $statement->execute();
261
262
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
263
    }
264
265
    /**
266
     * Loads a role draft by the original role ID.
267
     *
268
     * @param mixed $roleId ID of the role the draft was created from.
269
     *
270
     * @return array
271
     */
272
    public function loadRoleDraftByRoleId($roleId)
273
    {
274
        $query = $this->handler->createSelectQuery();
275
        $query->select(
276
            $this->handler->aliasedColumn($query, 'id', 'ezrole'),
277
            $this->handler->aliasedColumn($query, 'name', 'ezrole'),
278
            $this->handler->aliasedColumn($query, 'version', 'ezrole'),
279
            $this->handler->aliasedColumn($query, 'id', 'ezpolicy'),
280
            $this->handler->aliasedColumn($query, 'function_name', 'ezpolicy'),
281
            $this->handler->aliasedColumn($query, 'module_name', 'ezpolicy'),
282
            $this->handler->aliasedColumn($query, 'original_id', 'ezpolicy'),
283
            $this->handler->aliasedColumn($query, 'identifier', 'ezpolicy_limitation'),
284
            $this->handler->aliasedColumn($query, 'value', 'ezpolicy_limitation_value')
285
        )->from(
286
            $this->handler->quoteTable('ezrole')
287
        )->leftJoin(
288
            $this->handler->quoteTable('ezpolicy'),
289
            $query->expr->eq(
290
                $this->handler->quoteColumn('role_id', 'ezpolicy'),
291
                $this->handler->quoteColumn('id', 'ezrole')
292
            )
293
        )->leftJoin(
294
            $this->handler->quoteTable('ezpolicy_limitation'),
295
            $query->expr->eq(
296
                $this->handler->quoteColumn('policy_id', 'ezpolicy_limitation'),
297
                $this->handler->quoteColumn('id', 'ezpolicy')
298
            )
299
        )->leftJoin(
300
            $this->handler->quoteTable('ezpolicy_limitation_value'),
301
            $query->expr->eq(
302
                $this->handler->quoteColumn('limitation_id', 'ezpolicy_limitation_value'),
303
                $this->handler->quoteColumn('id', 'ezpolicy_limitation')
304
            )
305
        )->where(
306
            $query->expr->eq(
307
                // Column name "version" is misleading as it stores originalId when creating a draft from an existing role.
308
                // But hey, this is legacy! :-)
309
                $this->handler->quoteColumn('version', 'ezrole'),
310
                $query->bindValue($roleId, null, \PDO::PARAM_STR)
311
            )
312
        );
313
314
        $statement = $query->prepare();
315
        $statement->execute();
316
317
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
318
    }
319
320
    /**
321
     * Loads all roles.
322
     *
323
     * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT
324
     *
325
     * @return array
326
     */
327
    public function loadRoles($status = Role::STATUS_DEFINED)
328
    {
329
        $query = $this->handler->createSelectQuery();
330
        if ($status === Role::STATUS_DEFINED) {
331
            $roleVersionCondition = $query->expr->eq(
332
                $this->handler->quoteColumn('version', 'ezrole'),
333
                $query->bindValue($status, null, \PDO::PARAM_INT)
334
            );
335
        } else {
336
            $roleVersionCondition = $query->expr->neq(
337
                $this->handler->quoteColumn('version', 'ezrole'),
338
                $query->bindValue($status, null, \PDO::PARAM_INT)
339
            );
340
        }
341
342
        $query->select(
343
            $this->handler->aliasedColumn($query, 'id', 'ezrole'),
344
            $this->handler->aliasedColumn($query, 'name', 'ezrole'),
345
            $this->handler->aliasedColumn($query, 'version', 'ezrole'),
346
            $this->handler->aliasedColumn($query, 'contentobject_id', 'ezuser_role'),
347
            $this->handler->aliasedColumn($query, 'id', 'ezpolicy'),
348
            $this->handler->aliasedColumn($query, 'function_name', 'ezpolicy'),
349
            $this->handler->aliasedColumn($query, 'module_name', 'ezpolicy'),
350
            $this->handler->aliasedColumn($query, 'original_id', 'ezpolicy'),
351
            $this->handler->aliasedColumn($query, 'identifier', 'ezpolicy_limitation'),
352
            $this->handler->aliasedColumn($query, 'value', 'ezpolicy_limitation_value')
353
        )->from(
354
            $this->handler->quoteTable('ezrole')
355
        )->leftJoin(
356
            $this->handler->quoteTable('ezuser_role'),
357
            $query->expr->eq(
358
                $this->handler->quoteColumn('role_id', 'ezuser_role'),
359
                $this->handler->quoteColumn('id', 'ezrole')
360
            )
361
        )->leftJoin(
362
            $this->handler->quoteTable('ezpolicy'),
363
            $query->expr->eq(
364
                $this->handler->quoteColumn('role_id', 'ezpolicy'),
365
                $this->handler->quoteColumn('id', 'ezrole')
366
            )
367
        )->leftJoin(
368
            $this->handler->quoteTable('ezpolicy_limitation'),
369
            $query->expr->eq(
370
                $this->handler->quoteColumn('policy_id', 'ezpolicy_limitation'),
371
                $this->handler->quoteColumn('id', 'ezpolicy')
372
            )
373
        )->leftJoin(
374
            $this->handler->quoteTable('ezpolicy_limitation_value'),
375
            $query->expr->eq(
376
                $this->handler->quoteColumn('limitation_id', 'ezpolicy_limitation_value'),
377
                $this->handler->quoteColumn('id', 'ezpolicy_limitation')
378
            )
379
        )->where($roleVersionCondition);
380
381
        $statement = $query->prepare();
382
        $statement->execute();
383
384
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
385
    }
386
387
    /**
388
     * Loads all roles associated with the given content objects.
389
     *
390
     * @param array $contentIds
391
     * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT
392
     *
393
     * @return array
394
     */
395
    public function loadRolesForContentObjects($contentIds, $status = Role::STATUS_DEFINED)
396
    {
397
        $query = $this->handler->createSelectQuery();
398
        if ($status === Role::STATUS_DEFINED) {
399
            $roleIdCondition = $query->expr->eq(
400
                $this->handler->quoteColumn('id', 'ezrole'),
401
                $this->handler->quoteColumn('role_id', 'ezuser_role_search')
402
            );
403
        } else {
404
            $roleIdCondition = $query->expr->eq(
405
                $this->handler->quoteColumn('version', 'ezrole'),
406
                $this->handler->quoteColumn('role_id', 'ezuser_role_search')
407
            );
408
        }
409
410
        $query->select(
411
            $this->handler->aliasedColumn($query, 'contentobject_id', 'ezuser_role'),
412
            $this->handler->aliasedColumn($query, 'id', 'ezrole'),
413
            $this->handler->aliasedColumn($query, 'name', 'ezrole'),
414
            $this->handler->aliasedColumn($query, 'version', 'ezrole'),
415
            $this->handler->aliasedColumn($query, 'id', 'ezpolicy'),
416
            $this->handler->aliasedColumn($query, 'function_name', 'ezpolicy'),
417
            $this->handler->aliasedColumn($query, 'module_name', 'ezpolicy'),
418
            $this->handler->aliasedColumn($query, 'original_id', 'ezpolicy'),
419
            $this->handler->aliasedColumn($query, 'identifier', 'ezpolicy_limitation'),
420
            $this->handler->aliasedColumn($query, 'value', 'ezpolicy_limitation_value')
421
        )->from(
422
            $query->alias(
423
                $this->handler->quoteTable('ezuser_role'),
424
                $this->handler->quoteIdentifier('ezuser_role_search')
425
            )
426
        )->leftJoin(
427
            $this->handler->quoteTable('ezrole'),
428
            $roleIdCondition
429
        )->leftJoin(
430
            $this->handler->quoteTable('ezuser_role'),
431
            $query->expr->eq(
432
                $this->handler->quoteColumn('role_id', 'ezuser_role'),
433
                $this->handler->quoteColumn('id', 'ezrole')
434
            )
435
        )->leftJoin(
436
            $this->handler->quoteTable('ezpolicy'),
437
            $query->expr->eq(
438
                $this->handler->quoteColumn('role_id', 'ezpolicy'),
439
                $this->handler->quoteColumn('id', 'ezrole')
440
            )
441
        )->leftJoin(
442
            $this->handler->quoteTable('ezpolicy_limitation'),
443
            $query->expr->eq(
444
                $this->handler->quoteColumn('policy_id', 'ezpolicy_limitation'),
445
                $this->handler->quoteColumn('id', 'ezpolicy')
446
            )
447
        )->leftJoin(
448
            $this->handler->quoteTable('ezpolicy_limitation_value'),
449
            $query->expr->eq(
450
                $this->handler->quoteColumn('limitation_id', 'ezpolicy_limitation_value'),
451
                $this->handler->quoteColumn('id', 'ezpolicy_limitation')
452
            )
453
        )->where(
454
            $query->expr->in(
455
                $this->handler->quoteColumn('contentobject_id', 'ezuser_role_search'),
456
                $contentIds
457
            )
458
        );
459
460
        $statement = $query->prepare();
461
        $statement->execute();
462
463
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
464
    }
465
466
    /**
467
     * Loads role assignment for specified assignment ID.
468
     *
469
     * @param mixed $roleAssignmentId
470
     *
471
     * @return array
472
     */
473 View Code Duplication
    public function loadRoleAssignment($roleAssignmentId)
474
    {
475
        $query = $this->handler->createSelectQuery();
476
        $query->select(
477
            $this->handler->quoteColumn('id'),
478
            $this->handler->quoteColumn('contentobject_id'),
479
            $this->handler->quoteColumn('limit_identifier'),
480
            $this->handler->quoteColumn('limit_value'),
481
            $this->handler->quoteColumn('role_id')
482
        )->from(
483
            $this->handler->quoteTable('ezuser_role')
484
        )->where(
485
            $query->expr->eq(
486
                $this->handler->quoteColumn('id'),
487
                $query->bindValue($roleAssignmentId, null, \PDO::PARAM_INT)
488
            )
489
        );
490
491
        $statement = $query->prepare();
492
        $statement->execute();
493
494
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
495
    }
496
497
    /**
498
     * Loads role assignments for specified content ID.
499
     *
500
     * @param mixed $groupId
501
     * @param bool $inherited
502
     *
503
     * @return array
504
     */
505
    public function loadRoleAssignmentsByGroupId($groupId, $inherited = false)
506
    {
507
        $query = $this->handler->createSelectQuery();
508
        $query->select(
509
            $this->handler->quoteColumn('id'),
510
            $this->handler->quoteColumn('contentobject_id'),
511
            $this->handler->quoteColumn('limit_identifier'),
512
            $this->handler->quoteColumn('limit_value'),
513
            $this->handler->quoteColumn('role_id')
514
        )->from(
515
            $this->handler->quoteTable('ezuser_role')
516
        );
517
518
        if ($inherited) {
519
            $groupIds = $this->fetchUserGroups($groupId);
520
            $groupIds[] = $groupId;
521
            $query->where(
522
                $query->expr->in(
523
                    $this->handler->quoteColumn('contentobject_id'),
524
                    $groupIds
525
                )
526
            );
527
        } else {
528
            $query->where(
529
                $query->expr->eq(
530
                    $this->handler->quoteColumn('contentobject_id'),
531
                    $query->bindValue($groupId, null, \PDO::PARAM_INT)
532
                )
533
            );
534
        }
535
536
        $statement = $query->prepare();
537
        $statement->execute();
538
539
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
540
    }
541
542
    /**
543
     * Loads role assignments for given role ID.
544
     *
545
     * @param mixed $roleId
546
     *
547
     * @return array
548
     */
549 View Code Duplication
    public function loadRoleAssignmentsByRoleId($roleId)
550
    {
551
        $query = $this->handler->createSelectQuery();
552
        $query->select(
553
            $this->handler->quoteColumn('id'),
554
            $this->handler->quoteColumn('contentobject_id'),
555
            $this->handler->quoteColumn('limit_identifier'),
556
            $this->handler->quoteColumn('limit_value'),
557
            $this->handler->quoteColumn('role_id')
558
        )->from(
559
            $this->handler->quoteTable('ezuser_role')
560
        )->where(
561
            $query->expr->eq(
562
                $this->handler->quoteColumn('role_id'),
563
                $query->bindValue($roleId, null, \PDO::PARAM_INT)
564
            )
565
        );
566
567
        $statement = $query->prepare();
568
        $statement->execute();
569
570
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
571
    }
572
573
    /**
574
     * Returns the user policies associated with the user.
575
     *
576
     * @param mixed $userId
577
     *
578
     * @return UserPolicy[]
579
     */
580
    public function loadPoliciesByUserId($userId)
581
    {
582
        $groupIds = $this->fetchUserGroups($userId);
583
        $groupIds[] = $userId;
584
585
        return $this->loadRolesForContentObjects($groupIds);
586
    }
587
588
    /**
589
     * Fetch all group IDs the user belongs to.
590
     *
591
     * This method will return Content ids of all ancestor Locations for the given $userId.
592
     * Note that not all of these might be used as user groups,
593
     * but we will need to check all of them.
594
     *
595
     * @param int $userId
596
     *
597
     * @return array
598
     */
599
    protected function fetchUserGroups($userId)
600
    {
601
        $query = $this->handler->createSelectQuery();
602
        $query->select(
603
            $this->handler->quoteColumn('path_string', 'ezcontentobject_tree')
604
        )->from(
605
            $this->handler->quoteTable('ezcontentobject_tree')
606
        )->where(
607
            $query->expr->eq(
608
                $this->handler->quoteColumn('contentobject_id', 'ezcontentobject_tree'),
609
                $query->bindValue($userId)
610
            )
611
        );
612
613
        $statement = $query->prepare();
614
        $statement->execute();
615
616
        $paths = $statement->fetchAll(\PDO::FETCH_COLUMN);
617
        $nodeIDs = array_unique(
618
            array_reduce(
619
                array_map(
620
                    function ($pathString) {
621
                        return array_filter(explode('/', $pathString));
622
                    },
623
                    $paths
624
                ),
625
                'array_merge_recursive',
626
                []
627
            )
628
        );
629
630
        if (empty($nodeIDs)) {
631
            return [];
632
        }
633
634
        $query = $this->handler->createSelectQuery();
635
        $query->select(
636
            $this->handler->quoteColumn('id', 'ezcontentobject')
637
        )->from(
638
            $this->handler->quoteTable('ezcontentobject_tree')
639
        )->innerJoin(
640
            $this->handler->quoteTable('ezcontentobject'),
641
            $query->expr->eq(
642
                $this->handler->quoteColumn('id', 'ezcontentobject'),
643
                $this->handler->quoteColumn('contentobject_id', 'ezcontentobject_tree')
644
            )
645
        )->where(
646
            $query->expr->in(
647
                $this->handler->quoteColumn('node_id', 'ezcontentobject_tree'),
648
                $nodeIDs
649
            )
650
        );
651
652
        $statement = $query->prepare();
653
        $statement->execute();
654
655
        return $statement->fetchAll(\PDO::FETCH_COLUMN);
656
    }
657
658
    /**
659
     * Update role (draft).
660
     *
661
     * Will not throw anything if location id is invalid.
662
     *
663
     * @param \eZ\Publish\SPI\Persistence\User\RoleUpdateStruct $role
664
     *
665
     * @return array
666
     */
667 View Code Duplication
    public function updateRole(RoleUpdateStruct $role)
668
    {
669
        $query = $this->handler->createUpdateQuery();
670
        $query
671
            ->update($this->handler->quoteTable('ezrole'))
672
            ->set(
673
                $this->handler->quoteColumn('name'),
674
                $query->bindValue($role->identifier)
675
            )->where(
676
                $query->expr->eq(
677
                    $this->handler->quoteColumn('id'),
678
                    $query->bindValue($role->id, null, \PDO::PARAM_INT)
679
                )
680
            );
681
        $statement = $query->prepare();
682
        $statement->execute();
683
684
        // Commented due to EZP-24698: Role update leads to NotFoundException
685
        // Should be fixed with PDO::MYSQL_ATTR_FOUND_ROWS instead
686
        /*if ($statement->rowCount() < 1) {
687
            throw new NotFoundException('role', $role->id);
688
        }*/
689
    }
690
691
    /**
692
     * Delete the specified role (draft).
693
     * If it's not a draft, the role assignments will also be deleted.
694
     *
695
     * @param mixed $roleId
696
     * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT
697
     */
698
    public function deleteRole($roleId, $status = Role::STATUS_DEFINED)
699
    {
700
        $deleteRoleQuery = $this->handler->createDeleteQuery();
701
        if ($status !== Role::STATUS_DRAFT) {
702
            $deleteAssignmentsQuery = $this->handler->createDeleteQuery();
703
            $deleteAssignmentsQuery
704
                ->deleteFrom($this->handler->quoteTable('ezuser_role'))
705
                ->where(
706
                    $deleteAssignmentsQuery->expr->eq(
707
                        $this->handler->quoteColumn('role_id'),
708
                        $deleteAssignmentsQuery->bindValue($roleId, null, \PDO::PARAM_INT)
709
                    )
710
                );
711
712
            $draftCondition = $deleteRoleQuery->expr->eq(
713
                $this->handler->quoteColumn('version', 'ezrole'),
714
                $deleteRoleQuery->bindValue(Role::STATUS_DEFINED, null, \PDO::PARAM_INT)
715
            );
716
        } else {
717
            $draftCondition = $deleteRoleQuery->expr->neq(
718
                $this->handler->quoteColumn('version', 'ezrole'),
719
                $deleteRoleQuery->bindValue(Role::STATUS_DEFINED, null, \PDO::PARAM_INT)
720
            );
721
        }
722
723
        $deleteRoleQuery
724
            ->deleteFrom($this->handler->quoteTable('ezrole'))
725
            ->where(
726
                $deleteRoleQuery->expr->lAnd(
727
                    $deleteRoleQuery->expr->eq(
728
                        $this->handler->quoteColumn('id'),
729
                        $deleteRoleQuery->bindValue($roleId, null, \PDO::PARAM_INT)
730
                    ),
731
                    $draftCondition
732
                )
733
            );
734
735
        if ($status !== Role::STATUS_DRAFT) {
736
            $deleteAssignmentsQuery->prepare()->execute();
0 ignored issues
show
Bug introduced by
The variable $deleteAssignmentsQuery does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
737
        }
738
        $deleteRoleQuery->prepare()->execute();
739
    }
740
741
    /**
742
     * Publish the specified role draft.
743
     * If the draft was created from an existing role, published version will take the original role ID.
744
     *
745
     * @param mixed $roleDraftId
746
     * @param mixed|null $originalRoleId ID of role the draft was created from. Will be null if the role draft was completely new.
747
     */
748
    public function publishRoleDraft($roleDraftId, $originalRoleId = null)
749
    {
750
        $query = $this->handler->createUpdateQuery();
751
        $query
752
            ->update($this->handler->quoteTable('ezrole'))
753
            ->set(
754
                $this->handler->quoteColumn('version'),
755
                $query->bindValue(Role::STATUS_DEFINED, null, \PDO::PARAM_INT)
756
            );
757
        // Draft was created from an existing role, so published role must get the original ID.
758
        if ($originalRoleId !== null) {
759
            $query->set(
760
                $this->handler->quoteColumn('id'),
761
                $query->bindValue($originalRoleId, null, \PDO::PARAM_INT)
762
            );
763
        }
764
765
        $query->where(
766
            $query->expr->eq(
767
                $this->handler->quoteColumn('id'),
768
                $query->bindValue($roleDraftId, null, \PDO::PARAM_INT)
769
            )
770
        );
771
        $statement = $query->prepare();
772
        $statement->execute();
773
774
        $policyQuery = $this->handler->createUpdateQuery();
775
        $policyQuery
776
            ->update($this->handler->quoteTable('ezpolicy'))
777
            ->set(
778
                $this->handler->quoteColumn('original_id'),
779
                $policyQuery->bindValue(0, null, \PDO::PARAM_INT)
780
            );
781
        // Draft was created from an existing role, so published policies must get the original role ID.
782
        if ($originalRoleId !== null) {
783
            $policyQuery->set(
784
                $this->handler->quoteColumn('role_id'),
785
                $policyQuery->bindValue($originalRoleId, null, \PDO::PARAM_INT)
786
            );
787
        }
788
789
        $policyQuery->where(
790
            $policyQuery->expr->eq(
791
                $this->handler->quoteColumn('role_id'),
792
                $policyQuery->bindValue($roleDraftId, null, \PDO::PARAM_INT)
793
            )
794
        );
795
        $queryStatement = $policyQuery->prepare();
796
        $queryStatement->execute();
797
    }
798
799
    /**
800
     * Adds a policy to a role.
801
     *
802
     * @param mixed $roleId
803
     * @param \eZ\Publish\SPI\Persistence\User\Policy $policy
804
     *
805
     * @return Policy
806
     */
807
    public function addPolicy($roleId, Policy $policy)
808
    {
809
        $query = $this->handler->createInsertQuery();
810
        $query
811
            ->insertInto($this->handler->quoteTable('ezpolicy'))
812
            ->set(
813
                $this->handler->quoteColumn('id'),
814
                $this->handler->getAutoIncrementValue('ezpolicy', 'id')
815
            )->set(
816
                $this->handler->quoteColumn('function_name'),
817
                $query->bindValue($policy->function)
818
            )->set(
819
                $this->handler->quoteColumn('module_name'),
820
                $query->bindValue($policy->module)
821
            )->set(
822
                $this->handler->quoteColumn('original_id'),
823
                $query->bindValue($policy->originalId ?: 0, null, \PDO::PARAM_INT)
824
            )->set(
825
                $this->handler->quoteColumn('role_id'),
826
                $query->bindValue($roleId, null, \PDO::PARAM_INT)
827
            );
828
        $query->prepare()->execute();
829
830
        $policy->id = $this->handler->lastInsertId(
831
            $this->handler->getSequenceName('ezpolicy', 'id')
832
        );
833
834
        $policy->roleId = $roleId;
835
836
        // Handle the only valid non-array value "*" by not inserting
837
        // anything. Still has not been documented by eZ Systems. So we
838
        // assume this is the right way to handle it.
839
        if (is_array($policy->limitations)) {
840
            $this->addPolicyLimitations($policy->id, $policy->limitations);
841
        }
842
843
        return $policy;
844
    }
845
846
    /**
847
     * Adds limitations to an existing policy.
848
     *
849
     * @param int $policyId
850
     * @param array $limitations
851
     */
852
    public function addPolicyLimitations($policyId, array $limitations)
853
    {
854
        foreach ($limitations as $identifier => $values) {
855
            $query = $this->handler->createInsertQuery();
856
            $query
857
                ->insertInto($this->handler->quoteTable('ezpolicy_limitation'))
858
                ->set(
859
                    $this->handler->quoteColumn('id'),
860
                    $this->handler->getAutoIncrementValue('ezpolicy_limitation', 'id')
861
                )->set(
862
                    $this->handler->quoteColumn('identifier'),
863
                    $query->bindValue($identifier)
864
                )->set(
865
                    $this->handler->quoteColumn('policy_id'),
866
                    $query->bindValue($policyId, null, \PDO::PARAM_INT)
867
                );
868
            $query->prepare()->execute();
869
870
            $limitationId = $this->handler->lastInsertId(
871
                $this->handler->getSequenceName('ezpolicy_limitation', 'id')
872
            );
873
874
            foreach ($values as $value) {
875
                $query = $this->handler->createInsertQuery();
876
                $query
877
                    ->insertInto($this->handler->quoteTable('ezpolicy_limitation_value'))
878
                    ->set(
879
                        $this->handler->quoteColumn('id'),
880
                        $this->handler->getAutoIncrementValue('ezpolicy_limitation_value', 'id')
881
                    )->set(
882
                        $this->handler->quoteColumn('value'),
883
                        $query->bindValue($value)
884
                    )->set(
885
                        $this->handler->quoteColumn('limitation_id'),
886
                        $query->bindValue($limitationId, null, \PDO::PARAM_INT)
887
                    );
888
                $query->prepare()->execute();
889
            }
890
        }
891
    }
892
893
    /**
894
     * Removes a policy from a role.
895
     *
896
     * @param mixed $policyId
897
     */
898
    public function removePolicy($policyId)
899
    {
900
        $this->removePolicyLimitations($policyId);
901
902
        $query = $this->handler->createDeleteQuery();
903
        $query
904
            ->deleteFrom($this->handler->quoteTable('ezpolicy'))
905
            ->where(
906
                $query->expr->eq(
907
                    $this->handler->quoteColumn('id'),
908
                    $query->bindValue($policyId, null, \PDO::PARAM_INT)
909
                )
910
            );
911
        $query->prepare()->execute();
912
    }
913
914
    /**
915
     * Remove all limitations for a policy.
916
     *
917
     * @param mixed $policyId
918
     */
919
    public function removePolicyLimitations($policyId)
920
    {
921
        $query = $this->handler->createSelectQuery();
922
        $query->select(
923
            $this->handler->aliasedColumn($query, 'id', 'ezpolicy_limitation'),
924
            $this->handler->aliasedColumn($query, 'id', 'ezpolicy_limitation_value')
925
        )->from(
926
            $this->handler->quoteTable('ezpolicy')
927
        )->leftJoin(
928
            $this->handler->quoteTable('ezpolicy_limitation'),
929
            $query->expr->eq(
930
                $this->handler->quoteColumn('policy_id', 'ezpolicy_limitation'),
931
                $this->handler->quoteColumn('id', 'ezpolicy')
932
            )
933
        )->leftJoin(
934
            $this->handler->quoteTable('ezpolicy_limitation_value'),
935
            $query->expr->eq(
936
                $this->handler->quoteColumn('limitation_id', 'ezpolicy_limitation_value'),
937
                $this->handler->quoteColumn('id', 'ezpolicy_limitation')
938
            )
939
        )->where(
940
            $query->expr->eq(
941
                $this->handler->quoteColumn('id', 'ezpolicy'),
942
                $query->bindValue($policyId, null, \PDO::PARAM_INT)
943
            )
944
        );
945
946
        $statement = $query->prepare();
947
        $statement->execute();
948
949
        $limitationIdsSet = [];
950
        $limitationValuesSet = [];
951
        while ($row = $statement->fetch(\PDO::FETCH_ASSOC)) {
952
            if ($row['ezpolicy_limitation_id'] !== null) {
953
                $limitationIdsSet[$row['ezpolicy_limitation_id']] = true;
954
            }
955
956
            if ($row['ezpolicy_limitation_value_id'] !== null) {
957
                $limitationValuesSet[$row['ezpolicy_limitation_value_id']] = true;
958
            }
959
        }
960
961 View Code Duplication
        if (!empty($limitationIdsSet)) {
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...
962
            $query = $this->handler->createDeleteQuery();
963
            $query
964
                ->deleteFrom($this->handler->quoteTable('ezpolicy_limitation'))
965
                ->where(
966
                    $query->expr->in($this->handler->quoteColumn('id'), array_keys($limitationIdsSet))
967
                );
968
            $query->prepare()->execute();
969
        }
970
971 View Code Duplication
        if (!empty($limitationValuesSet)) {
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...
972
            $query = $this->handler->createDeleteQuery();
973
            $query
974
                ->deleteFrom($this->handler->quoteTable('ezpolicy_limitation_value'))
975
                ->where(
976
                    $query->expr->in($this->handler->quoteColumn('id'), array_keys($limitationValuesSet))
977
                );
978
            $query->prepare()->execute();
979
        }
980
    }
981
}
982