Failed Conditions
Push — master ( 3b5f31...7e5acf )
by Adrien
16:34
created

AbstractModel   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Test Coverage

Coverage 88.46%

Importance

Changes 0
Metric Value
wmc 23
eloc 45
c 0
b 0
f 0
dl 0
loc 199
ccs 46
cts 52
cp 0.8846
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getCreationDate() 0 3 1
A setUpdateDate() 0 3 1
A getOwner() 0 3 1
A getCreator() 0 3 1
A setUpdater() 0 3 1
A getOwnerForCreation() 0 3 1
B setOwner() 0 19 8
A getUpdater() 0 3 1
A getUpdateDate() 0 3 1
A getPermissions() 0 9 1
A setCreator() 0 3 1
A getId() 0 3 1
A timestampCreation() 0 11 2
A setCreationDate() 0 3 1
A timestampUpdate() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Model;
6
7
use Application\Acl\Acl;
8
use Cake\Chronos\Chronos;
9
use Doctrine\ORM\Mapping as ORM;
10
use Ecodev\Felix\Api\Exception;
11
use Ecodev\Felix\Model\HasOwner;
12
use Ecodev\Felix\Model\Model;
13
use GraphQL\Doctrine\Annotation as API;
14
15
/**
16
 * Base class for all objects stored in database.
17
 *
18
 * It includes an automatic mechanism to timestamp objects with date and user.
19
 *
20
 * @ORM\MappedSuperclass
21
 * @ORM\HasLifecycleCallbacks
22
 * @API\Filters({
23
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\SearchOperatorType", type="string"),
24
 * })
25
 * @API\Sorting({
26
 *     "Application\Api\Input\Sorting\Owner"
27
 * })
28
 */
29
abstract class AbstractModel implements HasOwner, Model
30
{
31
    /**
32
     * @ORM\Column(type="integer")
33
     * @ORM\Id
34
     * @ORM\GeneratedValue(strategy="IDENTITY")
35
     */
36
    private ?int $id = null;
37
38
    /**
39
     * @ORM\Column(type="datetime", nullable=true)
40
     */
41
    private ?Chronos $creationDate = null;
42
43
    /**
44
     * @ORM\Column(type="datetime", nullable=true)
45
     */
46
    private ?Chronos $updateDate = null;
47
48
    /**
49
     * @ORM\ManyToOne(targetEntity="User")
50
     * @ORM\JoinColumns({
51
     *     @ORM\JoinColumn(onDelete="SET NULL")
52
     * })
53
     */
54
    private ?User $creator = null;
55
56
    /**
57
     * @ORM\ManyToOne(targetEntity="User")
58
     * @ORM\JoinColumns({
59
     *     @ORM\JoinColumn(onDelete="SET NULL")
60
     * })
61
     */
62
    private ?User $owner = null;
63
64
    /**
65
     * @ORM\ManyToOne(targetEntity="User")
66
     * @ORM\JoinColumns({
67
     *     @ORM\JoinColumn(onDelete="SET NULL")
68
     * })
69
     */
70
    private ?User $updater = null;
71
72
    /**
73
     * Get id.
74
     */
75 85
    public function getId(): ?int
76
    {
77 85
        return $this->id;
78
    }
79
80
    /**
81
     * Set creation date.
82
     */
83 58
    private function setCreationDate(Chronos $creationDate): void
84
    {
85 58
        $this->creationDate = $creationDate;
86
    }
87
88
    /**
89
     * Get creation date.
90
     */
91
    public function getCreationDate(): ?Chronos
92
    {
93
        return $this->creationDate;
94
    }
95
96
    /**
97
     * Set update date.
98
     */
99 71
    private function setUpdateDate(Chronos $updateDate): void
100
    {
101 71
        $this->updateDate = $updateDate;
102
    }
103
104
    /**
105
     * Get update date.
106
     */
107
    public function getUpdateDate(): ?Chronos
108
    {
109
        return $this->updateDate;
110
    }
111
112
    /**
113
     * Set creator.
114
     */
115 58
    private function setCreator(?User $creator): void
116
    {
117 58
        $this->creator = $creator;
118
    }
119
120
    /**
121
     * Get creator.
122
     */
123 1
    public function getCreator(): ?User
124
    {
125 1
        return $this->creator;
126
    }
127
128
    /**
129
     * Set owner.
130
     */
131 77
    public function setOwner(?User $owner): void
132
    {
133 77
        if ($owner === $this->owner) {
134 29
            return;
135
        }
136
137 72
        $user = User::getCurrent();
138 72
        $isAdmin = $user && $user->getRole() === User::ROLE_ADMINISTRATOR;
139 72
        $isOwner = $user === $this->owner;
140
141 72
        if ($this->owner && !$isAdmin && !$isOwner) {
142 1
            $currentLogin = $user ? $user->getLogin() : '[anonymous]';
143 1
            $currentOwnerLogin = $this->owner->getLogin();
0 ignored issues
show
Bug introduced by
The method getLogin() does not exist on null. ( Ignorable by Annotation )

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

143
            /** @scrutinizer ignore-call */ 
144
            $currentOwnerLogin = $this->owner->getLogin();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144 1
            $futureOwnerLogin = $owner ? $owner->getLogin() : '[nobody]';
145
146 1
            throw new Exception($currentLogin . ' is not allowed to change owner to ' . $futureOwnerLogin . ' because it belongs to ' . $currentOwnerLogin);
147
        }
148
149 72
        $this->owner = $owner;
150
    }
151
152
    /**
153
     * Get owner.
154
     */
155 102
    public function getOwner(): ?User
156
    {
157 102
        return $this->owner;
158
    }
159
160
    /**
161
     * Set updater.
162
     */
163 71
    private function setUpdater(?User $updater): void
164
    {
165 71
        $this->updater = $updater;
166
    }
167
168
    /**
169
     * Get updater.
170
     */
171
    public function getUpdater(): ?User
172
    {
173
        return $this->updater;
174
    }
175
176
    /**
177
     * Get default owner for creation.
178
     */
179 31
    protected function getOwnerForCreation(): ?User
180
    {
181 31
        return User::getCurrent();
182
    }
183
184
    /**
185
     * Automatically called by Doctrine when the object is saved for the first time.
186
     *
187
     * @ORM\PrePersist
188
     */
189 58
    public function timestampCreation(): void
190
    {
191 58
        $now = new Chronos();
192 58
        $user = User::getCurrent();
193 58
        $this->setCreationDate($now);
194 58
        $this->setUpdateDate($now);
195 58
        $this->setCreator($user);
196 58
        $this->setUpdater($user);
197
198 58
        if (!$this->getOwner()) {
199 36
            $this->setOwner($this->getOwnerForCreation());
200
        }
201
    }
202
203
    /**
204
     * Automatically called by Doctrine when the object is updated.
205
     *
206
     * @ORM\PreUpdate
207
     */
208 21
    public function timestampUpdate(): void
209
    {
210 21
        $this->setUpdateDate(new Chronos());
211 21
        $this->setUpdater(User::getCurrent());
212
    }
213
214
    /**
215
     * Get permissions on this object for the current user.
216
     *
217
     * @API\Field(type="Permissions")
218
     */
219 3
    public function getPermissions(): array
220
    {
221 3
        $acl = new Acl();
222
223
        return [
224 3
            'create' => $acl->isCurrentUserAllowed($this, 'create'),
225 3
            'read' => $acl->isCurrentUserAllowed($this, 'read'),
226 3
            'update' => $acl->isCurrentUserAllowed($this, 'update'),
227 3
            'delete' => $acl->isCurrentUserAllowed($this, 'delete'),
228
        ];
229
    }
230
}
231