Failed Conditions
Push — master ( 7ddf51...0a0c4a )
by Adrien
06:37
created

AbstractModel::setOwner()   B

Complexity

Conditions 9
Paths 19

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 11
nc 19
nop 1
dl 0
loc 19
ccs 12
cts 12
cp 1
crap 9
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Model;
6
7
use Application\Acl\Acl;
8
use Application\Api\Exception;
9
use Application\Utility;
10
use Cake\Chronos\Chronos;
11
use Doctrine\ORM\Mapping as ORM;
12
use GraphQL\Doctrine\Annotation as API;
13
14
/**
15
 * Base class for all objects stored in database.
16
 *
17
 * It includes an automatic mechanism to timestamp objects with date and user.
18
 *
19
 * @ORM\MappedSuperclass
20
 * @ORM\HasLifecycleCallbacks
21
 * @API\Filters({
22
 *     @API\Filter(field="custom", operator="Application\Api\Input\Operator\SearchOperatorType", type="string"),
23
 * })
24
 */
25
abstract class AbstractModel
26
{
27
    /**
28
     * @var int
29
     *
30
     * @ORM\Column(type="integer", nullable=false)
31
     * @ORM\Id
32
     * @ORM\GeneratedValue(strategy="IDENTITY")
33
     */
34
    private $id;
35
36
    /**
37
     * @var Chronos
38
     *
39
     * @ORM\Column(type="datetime", nullable=true)
40
     */
41
    private $creationDate;
42
43
    /**
44
     * @var Chronos
45
     *
46
     * @ORM\Column(type="datetime", nullable=true)
47
     */
48
    private $updateDate;
49
50
    /**
51
     * @var User
52
     *
53
     * @ORM\ManyToOne(targetEntity="User")
54
     */
55
    private $creator;
56
57
    /**
58
     * @var User
59
     *
60
     * @ORM\ManyToOne(targetEntity="User")
61
     */
62
    private $owner;
63
64
    /**
65
     * @var User
66
     *
67
     * @ORM\ManyToOne(targetEntity="User")
68
     */
69
    private $updater;
70
71
    /**
72
     * Get id
73
     *
74
     * @return null|int
75
     */
76 17
    public function getId(): ?int
77
    {
78 17
        return $this->id;
79
    }
80
81
    /**
82
     * Set creation date
83
     *
84
     * @param Chronos $creationDate
85
     */
86 6
    private function setCreationDate(Chronos $creationDate = null): void
87
    {
88 6
        $this->creationDate = $creationDate;
89 6
    }
90
91
    /**
92
     * Get creation date
93
     *
94
     * @return null|Chronos
95
     */
96
    public function getCreationDate(): ?Chronos
97
    {
98
        return $this->creationDate;
99
    }
100
101
    /**
102
     * Set update date
103
     *
104
     * @param Chronos $updateDate
105
     */
106 3
    private function setUpdateDate(Chronos $updateDate = null): void
107
    {
108 3
        $this->updateDate = $updateDate;
109 3
    }
110
111
    /**
112
     * Get update date
113
     *
114
     * @return null|Chronos
115
     */
116
    public function getUpdateDate(): ?Chronos
117
    {
118
        return $this->updateDate;
119
    }
120
121
    /**
122
     * Set creator
123
     *
124
     * @param User $creator
125
     */
126 6
    private function setCreator(User $creator = null): void
127
    {
128 6
        $this->creator = $creator;
129 6
    }
130
131
    /**
132
     * Get creator
133
     *
134
     * @return null|User
135
     */
136 1
    public function getCreator(): ?User
137
    {
138 1
        return $this->creator;
139
    }
140
141
    /**
142
     * Set owner
143
     *
144
     * @param User $owner
145
     */
146 16
    public function setOwner(User $owner = null): void
147
    {
148 16
        if ($owner === $this->owner) {
149 7
            return;
150
        }
151
152 14
        $user = User::getCurrent();
153 14
        $isAdmin = $user && $user->getRole() === User::ROLE_ADMINISTRATOR;
154 14
        $isOwner = $user === $this->owner;
155
156 14
        if ($this->owner && !$isAdmin && !$isOwner) {
157 1
            $currentLogin = $user ? $user->getLogin() : '[anonymous]';
158 1
            $currentOwnerLogin = $this->owner ? $this->owner->getLogin() : '[nobody]';
159 1
            $futureOwnerLogin = $owner ? $owner->getLogin() : '[nobody]';
160
161 1
            throw new Exception($currentLogin . ' is not allowed to change owner to ' . $futureOwnerLogin . ' because it belongs to ' . $currentOwnerLogin);
162
        }
163
164 14
        $this->owner = $owner;
165 14
    }
166
167
    /**
168
     * Get owner
169
     *
170
     * @return null|User
171
     */
172 9
    public function getOwner(): ?User
173
    {
174 9
        return $this->owner;
175
    }
176
177
    /**
178
     * Set updater
179
     *
180
     * @param null|User $updater
181
     */
182 3
    private function setUpdater(User $updater = null): void
183
    {
184 3
        $this->updater = $updater;
185 3
    }
186
187
    /**
188
     * Get updater
189
     *
190
     * @return null|User
191
     */
192
    public function getUpdater(): ?User
193
    {
194
        return $this->updater;
195
    }
196
197
    /**
198
     * Automatically called by Doctrine when the object is saved for the first time
199
     *
200
     * @ORM\PrePersist
201
     */
202 6
    public function timestampCreation(): void
203
    {
204 6
        $this->setCreationDate(Utility::getNow());
205 6
        $this->setCreator(User::getCurrent());
206 6
        $this->setOwner(User::getCurrent());
207 6
    }
208
209
    /**
210
     * Automatically called by Doctrine when the object is updated
211
     *
212
     * @ORM\PreUpdate
213
     */
214 3
    public function timestampUpdate(): void
215
    {
216 3
        $this->setUpdateDate(Utility::getNow());
217 3
        $this->setUpdater(User::getCurrent());
218 3
    }
219
220
    /**
221
     * Get permissions on this object for the current user
222
     *
223
     * @API\Field(type="Permissions")
224
     *
225
     * @return array
226
     */
227 3
    public function getPermissions(): array
228
    {
229 3
        $acl = new Acl();
230
231
        return [
232 3
            'create' => $acl->isCurrentUserAllowed($this, 'create'),
233 3
            'read' => $acl->isCurrentUserAllowed($this, 'read'),
234 3
            'update' => $acl->isCurrentUserAllowed($this, 'update'),
235 3
            'delete' => $acl->isCurrentUserAllowed($this, 'delete'),
236
        ];
237
    }
238
}
239