Completed
Push — master ( f92548...5447f3 )
by Marcel
03:46
created

AttributePersister::persist()   C

Complexity

Conditions 12
Paths 40

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 22
c 1
b 0
f 0
nc 40
nop 3
dl 0
loc 39
ccs 0
cts 23
cp 0
crap 156
rs 6.9666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Service;
4
5
use App\Entity\ServiceAttribute;
6
use App\Entity\ServiceAttributeRegistrationCodeValue;
7
use App\Entity\ServiceAttributeUserRoleValue;
8
use App\Entity\ServiceAttributeUserTypeValue;
9
use App\Entity\ServiceAttributeValue;
10
use App\Entity\User;
11
use App\Entity\RegistrationCode;
12
use App\Entity\UserRole;
13
use App\Entity\UserType;
14
use App\Repository\ServiceAttributeRepositoryInterface;
15
use App\Repository\ServiceAttributeValueRepositoryInterface;
16
use App\Repository\TransactionalRepositoryInterface;
17
use App\Traits\ArrayTrait;
18
19
/**
20
 * Helper which persists attributes of a user in the database.
21
 */
22
class AttributePersister {
23
    use ArrayTrait;
24
25
    private $attributeRepository;
26
    private $attributeValueRepository;
27
28
    public function __construct(ServiceAttributeRepositoryInterface $attributeRepository, ServiceAttributeValueRepositoryInterface $attributeValueRepository) {
29
        $this->attributeRepository = $attributeRepository;
30
        $this->attributeValueRepository = $attributeValueRepository;
31
    }
32
33
    public function persist(array $values, array $currentAttributes, \Closure $factory) {
34
        /** @var ServiceAttribute[] $attributes */
35
        $attributes = $this->makeArrayWithKeys(
36
            $this->attributeRepository->findAll(),
37
            function(ServiceAttribute $attribute) {
38
                return $attribute->getName();
39
            }
40
        );
41
42
        if($this->attributeValueRepository instanceof TransactionalRepositoryInterface) {
43
            $this->attributeValueRepository->beginTransaction();
0 ignored issues
show
Bug introduced by
The method beginTransaction() does not exist on App\Repository\ServiceAt...alueRepositoryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to App\Repository\ServiceAt...alueRepositoryInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

43
            $this->attributeValueRepository->/** @scrutinizer ignore-call */ 
44
                                             beginTransaction();
Loading history...
44
        }
45
46
        foreach($values as $name => $value) {
47
            if(!array_key_exists($name, $attributes)) {
48
                continue; // TODO: maybe throw Exception here?!
49
            }
50
51
            $currentAttributeValue = null;
52
53
            if (array_key_exists($name, $currentAttributes)) {
54
                $currentAttributeValue = $currentAttributes[$name];
55
            }
56
57
            if($currentAttributeValue !== null && ($value === null || empty($value))) {
58
                $this->attributeValueRepository->remove($currentAttributeValue);
59
            } elseif ($value !== null && !empty($value)) {
60
                if($currentAttributeValue === null) {
61
                    $currentAttributeValue = $factory();
62
                    $currentAttributeValue->setAttribute($attributes[$name]);
63
                }
64
65
                $currentAttributeValue->setValue($value);
66
                $this->attributeValueRepository->persist($currentAttributeValue);
67
            }
68
        }
69
70
        if($this->attributeValueRepository instanceof TransactionalRepositoryInterface) {
71
            $this->attributeValueRepository->commit();
0 ignored issues
show
Bug introduced by
The method commit() does not exist on App\Repository\ServiceAt...alueRepositoryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to App\Repository\ServiceAt...alueRepositoryInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
            $this->attributeValueRepository->/** @scrutinizer ignore-call */ 
72
                                             commit();
Loading history...
72
        }
73
    }
74
75
    public function persistUserAttributes(array $values, User $user) {
76
        $factory = function() use ($user) {
77
            $value = (new ServiceAttributeValue())
78
                ->setUser($user);
79
            $user->getAttributes()->add($value);
80
81
            return $value;
82
        };
83
84
        /** @var ServiceAttributeValue[] $currentUserAttributes */
85
        $currentUserAttributes = $this->makeArrayWithKeys(
86
            $user->getAttributes()->toArray(),
87
            function(ServiceAttributeValue $attributeValue) {
88
                return $attributeValue->getAttribute()->getName();
89
            }
90
        );
91
92
        $this->persist($values, $currentUserAttributes, $factory);
93
    }
94
95
    public function persistUserRoleAttributes(array $values, UserRole $userRole) {
96
        $factory = function() use ($userRole) {
97
            $value = (new ServiceAttributeUserRoleValue())
98
                ->setUserRole($userRole);
99
            $userRole->getAttributes()->add($value);
100
101
            return $value;
102
        };
103
104
        /** @var ServiceAttributeUserRoleValue[] $currentUserAttributes */
105
        $currentUserAttributes = $this->makeArrayWithKeys(
106
            $userRole->getAttributes()->toArray(),
107
            function(ServiceAttributeUserRoleValue $attributeValue) {
108
                return $attributeValue->getAttribute()->getName();
109
            }
110
        );
111
112
        $this->persist($values, $currentUserAttributes, $factory);
113
    }
114
115
    public function persistUserTypeAttributes(array $values, UserType $userType) {
116
        $factory = function() use ($userType) {
117
            $value = (new ServiceAttributeUserTypeValue())
118
                ->setUserType($userType);
119
            $userType->getAttributes()->add($value);
120
121
            return $value;
122
        };
123
124
        /** @var ServiceAttributeUserRoleValue[] $currentUserAttributes */
125
        $currentUserAttributes = $this->makeArrayWithKeys(
126
            $userType->getAttributes()->toArray(),
127
            function(ServiceAttributeUserTypeValue $attributeValue) {
128
                return $attributeValue->getAttribute()->getName();
129
            }
130
        );
131
132
        $this->persist($values, $currentUserAttributes, $factory);
133
    }
134
135
    public function persistRegistrationCodeAttributes(array $values, RegistrationCode $code) {
136
        $factory = function() use ($code) {
137
            $value = (new ServiceAttributeRegistrationCodeValue())
138
                ->setRegistrationCode($code);
139
            $code->getAttributes()->add($value);
140
141
            return $value;
142
        };
143
144
        $currentRegistrationCodeAttributes = $this->makeArrayWithKeys(
145
            $code->getAttributes()->toArray(),
146
            function(ServiceAttributeRegistrationCodeValue $attributeValue) {
147
                return $attributeValue->getAttribute()->getName();
148
            }
149
        );
150
151
        $this->persist($values, $currentRegistrationCodeAttributes, $factory);
152
    }
153
}