Passed
Push — master ( a8b983...5b3176 )
by Adrien
10:48
created

AbstractModel   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 207
Duplicated Lines 0 %

Test Coverage

Coverage 85.45%

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 207
ccs 47
cts 55
cp 0.8545
rs 10
c 0
b 0
f 0
wmc 23

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getCreationDate() 0 3 1
A setUpdateDate() 0 3 1
A getOwner() 0 3 1
A setUpdater() 0 3 1
B setOwner() 0 19 8
A getUpdater() 0 3 1
A getUpdateDate() 0 3 1
A getPermissions() 0 9 1
A setCreationDate() 0 3 1
A timestampUpdate() 0 4 1
A getCreator() 0 3 1
A getOwnerForCreation() 0 3 1
A setCreator() 0 3 1
A getId() 0 3 1
A timestampCreation() 0 7 2
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\LatestModification",
27
 *     "Application\Api\Input\Sorting\Owner"
28
 * })
29
 */
30
abstract class AbstractModel implements HasOwner, Model
31
{
32
    /**
33
     * @var int
34
     *
35
     * @ORM\Column(type="integer", nullable=false)
36
     * @ORM\Id
37
     * @ORM\GeneratedValue(strategy="IDENTITY")
38
     */
39
    private $id;
40
41
    /**
42
     * @var null|Chronos
43
     *
44
     * @ORM\Column(type="datetime", nullable=true)
45
     */
46
    private $creationDate;
47
48
    /**
49
     * @var null|Chronos
50
     *
51
     * @ORM\Column(type="datetime", nullable=true)
52
     */
53
    private $updateDate;
54
55
    /**
56
     * @var null|User
57
     *
58
     * @ORM\ManyToOne(targetEntity="User")
59
     * @ORM\JoinColumns({
60
     *     @ORM\JoinColumn(onDelete="SET NULL")
61
     * })
62
     */
63
    private $creator;
64
65
    /**
66
     * @var null|User
67
     *
68
     * @ORM\ManyToOne(targetEntity="User")
69
     * @ORM\JoinColumns({
70
     *     @ORM\JoinColumn(onDelete="SET NULL")
71
     * })
72
     */
73
    private $owner;
74
75
    /**
76
     * @var null|User
77
     *
78
     * @ORM\ManyToOne(targetEntity="User")
79
     * @ORM\JoinColumns({
80
     *     @ORM\JoinColumn(onDelete="SET NULL")
81
     * })
82
     */
83
    private $updater;
84
85
    /**
86
     * Get id
87
     */
88 36
    public function getId(): ?int
89
    {
90 36
        return $this->id;
91
    }
92
93
    /**
94
     * Set creation date
95
     */
96 35
    private function setCreationDate(Chronos $creationDate): void
97
    {
98 35
        $this->creationDate = $creationDate;
99 35
    }
100
101
    /**
102
     * Get creation date
103
     */
104
    public function getCreationDate(): ?Chronos
105
    {
106
        return $this->creationDate;
107
    }
108
109
    /**
110
     * Set update date
111
     */
112 10
    private function setUpdateDate(Chronos $updateDate): void
113
    {
114 10
        $this->updateDate = $updateDate;
115 10
    }
116
117
    /**
118
     * Get update date
119
     */
120
    public function getUpdateDate(): ?Chronos
121
    {
122
        return $this->updateDate;
123
    }
124
125
    /**
126
     * Set creator
127
     */
128 35
    private function setCreator(?User $creator): void
129
    {
130 35
        $this->creator = $creator;
131 35
    }
132
133
    /**
134
     * Get creator
135
     */
136
    public function getCreator(): ?User
137
    {
138
        return $this->creator;
139
    }
140
141
    /**
142
     * Set owner
143
     */
144 42
    public function setOwner(?User $owner): void
145
    {
146 42
        if ($owner === $this->owner) {
147 18
            return;
148
        }
149
150 29
        $user = User::getCurrent();
151 29
        $isAdmin = $user && $user->getRole() === User::ROLE_ADMINISTRATOR;
152 29
        $isOwner = $user === $this->owner;
153
154 29
        if ($this->owner && !$isAdmin && !$isOwner) {
155 1
            $currentLogin = $user ? $user->getName() : '[anonymous]';
156 1
            $currentOwnerLogin = $this->owner->getName();
0 ignored issues
show
Bug introduced by
The method getName() 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

156
            /** @scrutinizer ignore-call */ 
157
            $currentOwnerLogin = $this->owner->getName();

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...
157 1
            $futureOwnerLogin = $owner ? $owner->getName() : '[nobody]';
158
159 1
            throw new Exception($currentLogin . ' is not allowed to change owner to ' . $futureOwnerLogin . ' because it belongs to ' . $currentOwnerLogin);
160
        }
161
162 29
        $this->owner = $owner;
163 29
    }
164
165
    /**
166
     * Get owner
167
     */
168 43
    public function getOwner(): ?User
169
    {
170 43
        return $this->owner;
171
    }
172
173
    /**
174
     * Set updater
175
     */
176 10
    private function setUpdater(?User $updater): void
177
    {
178 10
        $this->updater = $updater;
179 10
    }
180
181
    /**
182
     * Get updater
183
     */
184
    public function getUpdater(): ?User
185
    {
186
        return $this->updater;
187
    }
188
189
    /**
190
     * Get default owner for creation
191
     */
192 16
    protected function getOwnerForCreation(): ?User
193
    {
194 16
        return User::getCurrent();
195
    }
196
197
    /**
198
     * Automatically called by Doctrine when the object is saved for the first time
199
     *
200
     * @ORM\PrePersist
201
     */
202 35
    public function timestampCreation(): void
203
    {
204 35
        $this->setCreationDate(new Chronos());
205 35
        $this->setCreator(User::getCurrent());
206
207 35
        if (!$this->getOwner()) {
208 18
            $this->setOwner($this->getOwnerForCreation());
209
        }
210 35
    }
211
212
    /**
213
     * Automatically called by Doctrine when the object is updated
214
     *
215
     * @ORM\PreUpdate
216
     */
217 10
    public function timestampUpdate(): void
218
    {
219 10
        $this->setUpdateDate(new Chronos());
220 10
        $this->setUpdater(User::getCurrent());
221 10
    }
222
223
    /**
224
     * Get permissions on this object for the current user
225
     *
226
     * @API\Field(type="Permissions")
227
     */
228 2
    public function getPermissions(): array
229
    {
230 2
        $acl = new Acl();
231
232
        return [
233 2
            'create' => $acl->isCurrentUserAllowed($this, 'create'),
234 2
            'read' => $acl->isCurrentUserAllowed($this, 'read'),
235 2
            'update' => $acl->isCurrentUserAllowed($this, 'update'),
236 2
            'delete' => $acl->isCurrentUserAllowed($this, 'delete'),
237
        ];
238
    }
239
}
240