ObjectAclManipulator   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 5

Importance

Changes 0
Metric Value
wmc 8
lcom 0
cbo 5
dl 0
loc 66
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B batchConfigureAcls() 0 63 8
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\DoctrineORMAdminBundle\Util;
15
16
use Sonata\AdminBundle\Admin\AdminInterface;
17
use Sonata\AdminBundle\Exception\ModelManagerException;
18
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
19
use Sonata\AdminBundle\Util\ObjectAclManipulator as BaseObjectAclManipulator;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
22
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
23
24
class ObjectAclManipulator extends BaseObjectAclManipulator
25
{
26
    public function batchConfigureAcls(OutputInterface $output, AdminInterface $admin, ?UserSecurityIdentity $securityIdentity = null): void
27
    {
28
        $securityHandler = $admin->getSecurityHandler();
29
        if (!$securityHandler instanceof AclSecurityHandlerInterface) {
30
            $output->writeln('Admin class is not configured to use ACL : <info>ignoring</info>');
31
32
            return;
33
        }
34
35
        $output->writeln(sprintf(' > generate ACLs for %s', $admin->getCode()));
36
        $objectOwnersMsg = null === $securityIdentity ? '' : ' and set the object owner';
37
38
        $em = $admin->getModelManager()->getEntityManager($admin->getClass());
39
        $qb = $em->createQueryBuilder();
40
        $qb->select('o')->from($admin->getClass(), 'o');
41
42
        $count = 0;
43
        $countUpdated = 0;
44
        $countAdded = 0;
45
46
        try {
47
            $batchSize = 20;
48
            $batchSizeOutput = 200;
49
            $objectIds = [];
50
51
            foreach ($qb->getQuery()->iterate() as $row) {
52
                $objectIds[] = ObjectIdentity::fromDomainObject($row[0]);
53
                $objectIdIterator = new \ArrayIterator($objectIds);
54
55
                // detach from Doctrine, so that it can be Garbage-Collected immediately
56
                $em->detach($row[0]);
57
58
                ++$count;
59
60
                if (0 === ($count % $batchSize)) {
61
                    list($batchAdded, $batchUpdated) = $this->configureAcls($output, $admin, $objectIdIterator, $securityIdentity);
62
                    $countAdded += $batchAdded;
63
                    $countUpdated += $batchUpdated;
64
                    $objectIds = [];
65
                }
66
67
                if (0 === ($count % $batchSizeOutput)) {
68
                    $output->writeln(sprintf('   - generated class ACEs%s for %s objects (added %s, updated %s)', $objectOwnersMsg, $count, $countAdded, $countUpdated));
69
                }
70
            }
71
72
            if (\count($objectIds) > 0) {
73
                list($batchAdded, $batchUpdated) = $this->configureAcls($output, $admin, $objectIdIterator, $securityIdentity);
0 ignored issues
show
Bug introduced by
The variable $objectIdIterator 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...
74
                $countAdded += $batchAdded;
75
                $countUpdated += $batchUpdated;
76
            }
77
        } catch (\PDOException $e) {
78
            throw new ModelManagerException('', 0, $e);
79
        }
80
81
        $output->writeln(sprintf(
82
            '   - [TOTAL] generated class ACEs%s for %s objects (added %s, updated %s)',
83
            $objectOwnersMsg,
84
            $count,
85
            $countAdded,
86
            $countUpdated
87
        ));
88
    }
89
}
90