BusinessUnitRepository   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 205
Duplicated Lines 3.41 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 2
Bugs 2 Features 2
Metric Value
wmc 26
lcom 1
cbo 7
dl 7
loc 205
rs 10
c 2
b 2
f 2

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getGridFilterChoices() 7 22 2
A getFirst() 0 9 1
C getBusinessUnitsTree() 0 47 10
A getBusinessUnitIds() 0 21 3
A getBusinessUnits() 0 9 1
A getBusinessUnitsCount() 0 7 1
C getOrganizationBusinessUnitsTree() 0 28 7
A getQueryBuilder() 0 4 1

How to fix   Duplicated Code   

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:

1
<?php
2
namespace Oro\Bundle\OrganizationBundle\Entity\Repository;
3
4
use Doctrine\ORM\EntityRepository;
5
use Doctrine\ORM\Query\Expr;
6
use Doctrine\ORM\QueryBuilder;
7
8
use Oro\Bundle\OrganizationBundle\Entity\BusinessUnit;
9
use Oro\Bundle\OrganizationBundle\Entity\Organization;
10
use Oro\Bundle\UserBundle\Entity\User;
11
12
class BusinessUnitRepository extends EntityRepository
13
{
14
    /**
15
     * Finds the first record
16
     *
17
     * @return BusinessUnit
18
     */
19
    public function getFirst()
20
    {
21
        return $this->createQueryBuilder('businessUnit')
22
            ->select('businessUnit')
23
            ->orderBy('businessUnit.id')
24
            ->getQuery()
25
            ->setMaxResults(1)
26
            ->getSingleResult();
27
    }
28
29
    /**
30
     * Build business units tree for user page
31
     *
32
     * @param User     $user
33
     * @param int|null $organizationId
34
     * @return array
35
     *
36
     * @SuppressWarnings(PHPMD.NPathComplexity)
37
     */
38
    public function getBusinessUnitsTree(User $user = null, $organizationId = null)
39
    {
40
        $businessUnits = $this->createQueryBuilder('businessUnit')->select(
41
            array(
42
                'businessUnit.id',
43
                'businessUnit.name',
44
                'IDENTITY(businessUnit.owner) parent',
45
                'IDENTITY(businessUnit.organization) organization',
46
            )
47
        );
48
        if ($user && $user->getId()) {
49
            $units = $user->getBusinessUnits()->map(
50
                function (BusinessUnit $businessUnit) {
51
                    return $businessUnit->getId();
52
                }
53
            );
54
            $units = $units->toArray();
55
            if ($units) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $units of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
56
                $businessUnits->addSelect('CASE WHEN businessUnit.id IN (:userUnits) THEN 1 ELSE 0 END as hasUser');
57
                $businessUnits->setParameter(':userUnits', $units);
58
            }
59
        }
60
61
        if ($organizationId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $organizationId of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
62
            $businessUnits->where('businessUnit.organization = :organizationId');
63
            $businessUnits->setParameter(':organizationId', $organizationId);
64
        }
65
66
        $businessUnits = $businessUnits->getQuery()->getArrayResult();
67
        $children      = array();
68
        foreach ($businessUnits as &$businessUnit) {
69
            $parent              = $businessUnit['parent'] ? : 0;
70
            $children[$parent][] = & $businessUnit;
71
        }
72
        unset($businessUnit);
73
        foreach ($businessUnits as &$businessUnit) {
74
            if (isset($children[$businessUnit['id']])) {
75
                $businessUnit['children'] = $children[$businessUnit['id']];
76
            }
77
        }
78
        unset($businessUnit);
79
        if (isset($children[0])) {
80
            $children = $children[0];
81
        }
82
83
        return $children;
84
    }
85
86
    /**
87
     * Returns business units tree by organization
88
     * Or returns business units tree for given organization.
89
     *
90
     * @param int|null $organizationId
91
     * @param array $sortOrder array with order parameters. key - organization entity field, value - sort direction
92
     *
93
     * @return array
94
     */
95
    public function getOrganizationBusinessUnitsTree($organizationId = null, array $sortOrder = [])
96
    {
97
        $tree          = [];
98
        $businessUnits = $this->getBusinessUnitsTree();
99
100
        $organizations = $this->_em->getRepository('OroOrganizationBundle:Organization')
101
            ->getOrganizationsPartialData(
102
                ['id', 'name', 'enabled'],
103
                $sortOrder,
104
                $organizationId ? [$organizationId] : []
105
            );
106
        foreach ($organizations as $organizationItem) {
107
            $tree[$organizationItem['id']] = array_merge($organizationItem, ['children' => []]);
108
        }
109
110
        foreach ($businessUnits as $businessUnit) {
111
            if ($businessUnit['organization'] == null) {
112
                continue;
113
            }
114
            $tree[$businessUnit['organization']]['children'][] = $businessUnit;
115
        }
116
117
        if ($organizationId && isset($tree[$organizationId])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $organizationId of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
118
            return $tree[$organizationId]['children'];
119
        }
120
121
        return $tree;
122
    }
123
124
    /**
125
     * Get business units ids
126
     *
127
     * @param int|null $organizationId
128
     * @return array
129
     */
130
    public function getBusinessUnitIds($organizationId = null)
131
    {
132
        $result        = [];
133
        /** @var QueryBuilder $businessUnitsQB */
134
        $businessUnitsQB = $this->createQueryBuilder('businessUnit');
135
        $businessUnitsQB->select('businessUnit.id');
136
        if ($organizationId != null) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $organizationId of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
137
            $businessUnitsQB
138
                ->where('businessUnit.organization = :organizationId')
139
                ->setParameter(':organizationId', $organizationId);
140
        }
141
        $businessUnits = $businessUnitsQB
142
            ->getQuery()
143
            ->getArrayResult();
144
145
        foreach ($businessUnits as $buId) {
146
            $result[] = $buId['id'];
147
        }
148
149
        return $result;
150
    }
151
152
    /**
153
     * @param array $businessUnits
154
     * @return mixed
155
     */
156
    public function getBusinessUnits(array $businessUnits)
157
    {
158
        return $this->createQueryBuilder('businessUnit')
159
            ->select('businessUnit')
160
            ->where('businessUnit.id in (:ids)')
161
            ->setParameter('ids', $businessUnits)
162
            ->getQuery()
163
            ->execute();
164
    }
165
166
    /**
167
     * Get count of business units
168
     *
169
     * @return int
170
     */
171
    public function getBusinessUnitsCount()
172
    {
173
        $qb = $this->createQueryBuilder('businessUnit');
174
        $qb->select('count(businessUnit.id)');
175
176
        return $qb->getQuery()->getSingleScalarResult();
177
    }
178
179
    /**
180
     * @param string $field
181
     * @param string $entity
182
     * @param string $alias
183
     *
184
     * @return array
185
     */
186
    public function getGridFilterChoices($field, $entity, $alias = 'bu')
187
    {
188
        $options = [];
189
190
        $result = $this->_em->createQueryBuilder()
191
            ->select($alias)
192
            ->from($entity, $alias)
193
            ->add('select', $alias . '.' . $field)
0 ignored issues
show
Documentation introduced by
$alias . '.' . $field is of type string, but the function expects a object<Doctrine\ORM\Query\Expr\Base>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
194
            ->distinct($alias . '.' . $field)
0 ignored issues
show
Documentation introduced by
$alias . '.' . $field is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
195
            ->getQuery()
196
            ->getArrayResult();
197
198 View Code Duplication
        foreach ((array)$result as $value) {
199
            $options[$value[$field]] = current(
200
                array_reverse(
201
                    explode('\\', $value[$field])
202
                )
203
            );
204
        }
205
206
        return $options;
207
    }
208
209
    /**
210
     * @return QueryBuilder
211
     */
212
    public function getQueryBuilder()
213
    {
214
        return $this->createQueryBuilder('businessUnit');
215
    }
216
}
217