Passed
Pull Request — master (#37)
by Rafael
05:21
created

Roles::existsById()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 9
ccs 4
cts 5
cp 0.8
crap 2.032
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Gewaer\Models;
5
6
use Gewaer\Exception\ServerErrorHttpException;
7
use Phalcon\Di;
8
use Phalcon\Validation;
9
use Phalcon\Validation\Validator\PresenceOf;
10
use Phalcon\Validation\Validator\StringLength;
11
use Phalcon\Acl\Role as AclRole;
12
use Gewaer\Exception\ModelException;
13
14
/**
15
 * Class Roles
16
 *
17
 * @package Gewaer\Models
18
 *
19
 * @property AccesList $accesList
20
 * @property \Phalcon\Di $di
21
 */
22
class Roles extends AbstractModel
23
{
24
    /**
25
     *
26
     * @var integer
27
     */
28
    public $id;
29
30
    /**
31
     *
32
     * @var string
33
     */
34
    public $name;
35
36
    /**
37
     *
38
     * @var string
39
     */
40
    public $description;
41
42
    /**
43
     *
44
     * @var integer
45
     */
46
    public $scope;
47
48
    /**
49
     *
50
     * @var integer
51
     */
52
    public $companies_id;
53
54
    /**
55
     *
56
     * @var int
57
     */
58
    public $apps_id;
59
60
    /**
61
     *
62
     * @var string
63
     */
64
    public $created_at;
65
66
    /**
67
     *
68
     * @var string
69
     */
70
    public $updated_at;
71
72
    /**
73
     *
74
     * @var integer
75
     */
76
    public $is_deleted;
77
78
    /**
79
     * Default ACL company
80
     *
81
     */
82
    const DEFAULT_ACL_COMPANY_ID = 0;
83
    const DEFAULT_ACL_APP_ID = 0;
84
85
    /**
86
     * Initialize method for model.
87
     */
88 21
    public function initialize()
89
    {
90 21
        $this->setSource('roles');
91
92 21
        $this->hasMany(
93 21
            'id',
94 21
            'Gewaer\Models\AccessList',
95 21
            'roles_id',
96 21
            ['alias' => 'accesList']
97
        );
98 21
    }
99
100
    /**
101
     * Validations and business logic
102
     */
103 4
    public function validation()
104
    {
105 4
        $validator = new Validation();
106
107 4
        $validator->add(
108 4
            'name',
109 4
            new PresenceOf([
110 4
                'field' => 'name',
111
                'required' => true,
112
            ])
113
        );
114
115 4
        $validator->add(
116 4
            'description',
117 4
            new PresenceOf([
118 4
                'field' => 'description',
119
                'required' => true,
120
            ])
121
        );
122
123 4
        $validator->add(
124 4
            'name',
125 4
            new StringLength([
126 4
                'max' => 32,
127 4
                'messageMinimum' => _('Role Name. Maxium 32 characters.'),
128
            ])
129
        );
130
131 4
        return $this->validate($validator);
132
    }
133
134
    /**
135
     * Returns table name mapped in the model.
136
     *
137
     * @return string
138
     */
139 20
    public function getSource(): string
140
    {
141 20
        return 'roles';
142
    }
143
144
    /**
145
     * Check if the role existe in the db
146
     *
147
     * @param AclRole $role
148
     * @return int
149
     */
150 3
    public static function exist(AclRole $role): int
151
    {
152 3
        return self::count([
153 3
            'conditions' => 'name = ?0 AND companies_id = ?1 AND apps_id = ?2',
154 3
            'bind' => [$role->getName(), Di::getDefault()->getAcl()->getCompany()->getId(), Di::getDefault()->getAcl()->getApp()->getId()]
155
        ]);
156
    }
157
158
    /**
159
     * check if this string is already a role
160
     * whats the diff with exist or why not merge them? exist uses the alc object and only check
161
     * with your current app, this also check with de defautl company ap
162
     *
163
     * @param string $roleName
164
     * @return boolean
165
     */
166 4
    public static function isRole(string $roleName) : bool
167
    {
168 4
        return (bool) self::count([
169 4
            'conditions' => 'name = ?0 AND apps_id in (?1, ?3) AND companies_id in (?2, ?3)',
170 4
            'bind' => [$roleName, Di::getDefault()->getAcl()->getApp()->getId(), Di::getDefault()->getAcl()->getCompany()->getId(), Apps::GEWAER_DEFAULT_APP_ID]
171
        ]);
172
    }
173
174
    /**
175
     * Get the entity by its name
176
     *
177
     * @param string $name
178
     * @return Roles
179
     */
180 8
    public static function getByName(string $name): Roles
181
    {
182 8
        $role = self::findFirst([
183 8
            'conditions' => 'name = ?0 AND apps_id in (?1, ?3) AND companies_id in (?2, ?3) AND is_deleted = 0',
184 8
            'bind' => [$name, Di::getDefault()->getAcl()->getApp()->getId(), Di::getDefault()->getAcl()->getCompany()->getId(), Apps::GEWAER_DEFAULT_APP_ID]
185
        ]);
186
187 8
        if (!is_object($role)) {
188
            throw new ModelException(_('Roles ' . $name . ' not found on this app ' . Di::getDefault()->getAcl()->getApp()->getId() . ' AND Company' . Di::getDefault()->getAcl()->getCompany()->getId()));
189
        }
190
191 8
        return $role;
192
    }
193
194
    /**
195
     * Get the entity by its name
196
     *
197
     * @param string $name
198
     * @return Roles
199
     */
200 6
    public static function getById(int $id): Roles
201
    {
202 6
        return self::findFirst([
203 6
            'conditions' => 'id = ?0 AND companies_id in (?1, ?2) AND apps_id in (?3, ?4) AND is_deleted = 0',
204 6
            'bind' => [$id, Di::getDefault()->getUserData()->currentCompanyId(), Apps::GEWAER_DEFAULT_APP_ID, Di::getDefault()->getApp()->getId(), Apps::GEWAER_DEFAULT_APP_ID]
205
        ]);
206
    }
207
208
    /**
209
     * Get the Role by it app name
210
     *
211
     * @param string $role
212
     * @return Roles
213
     */
214 3
    public static function getByAppName(string $role, Companies $company): Roles
215
    {
216
        //echeck if we have a dot , taht means we are sending the specific app to use
217 3
        if (strpos($role, '.') === false) {
218
            throw new ServerErrorHttpException('ACL - We are expecting the app for this role');
219
        }
220
221 3
        $appRole = explode('.', $role);
222 3
        $role = $appRole[1];
223 3
        $appName = $appRole[0];
224
225
        //look for the app and set it
226 3
        if (!$app = Apps::getACLApp($appName)) {
227
            throw new ServerErrorHttpException('ACL - No app found for this role');
228
        }
229
230 3
        return self::findFirst([
231 3
            'conditions' => 'apps_id in (?0, ?1) AND companies_id in (?2 , ?3)',
232 3
            'bind' => [$app->getId(), self::DEFAULT_ACL_APP_ID, $company->getId(), self::DEFAULT_ACL_COMPANY_ID]
233
        ]);
234
    }
235
236
    /**
237
     * Duplicate a role with it access list
238
     *
239
     * @return Roles
240
     */
241 1
    public function copy(): Roles
242
    {
243 1
        $accesList = $this->accesList;
244
245
        //remove id to create new record
246 1
        $this->name .= 'Copie';
247 1
        $this->scope = 1;
248 1
        $this->id = null;
249 1
        $this->companies_id = $this->di->getUserData()->currentCompanyId();
250 1
        $this->apps_id = $this->di->getApp()->getId();
251 1
        $this->save();
252
253 1
        foreach ($accesList as $access) {
254 1
            $copyAccessList = new AccessList();
255 1
            $copyAccessList->apps_id = $this->apps_id;
256 1
            $copyAccessList->roles_id = $this->getId();
257 1
            $copyAccessList->roles_name = $this->name;
258 1
            $copyAccessList->resources_name = $access->resources_name;
259 1
            $copyAccessList->access_name = $access->access_name;
260 1
            $copyAccessList->allowed = $access->allowed;
261 1
            $copyAccessList->create();
262
        }
263
264 1
        return $this;
265
    }
266
267
    /**
268
     * Add inherit to a given role
269
     *
270
     * @param string $roleName
271
     * @param string $roleToInherit
272
     * @return boolean
273
     */
274
    public static function addInherit(string $roleName, string $roleToInherit) : bool
275
    {
276
        $role = self::findFirstByName($roleName);
277
278
        if (!is_object($role)) {
279
            throw new ModelException("Role '{$roleName}' does not exist in the role list");
280
        }
281
282
        $inheritExist = RolesInherits::count([
283
            'conditions' => 'roles_name = ?0 and roles_inherit = ?1',
284
            'bind' => [$role->name, $roleToInherit]
285
        ]);
286
287
        if (!$inheritExist) {
288
            $rolesInHerits = new RolesInherits();
289
            $rolesInHerits->roles_id = $role->getId();
290
            $rolesInHerits->roles_inherit = (int) $roleToInherit;
291
292
            if (!$rolesInHerits->save()) {
293
                throw new ModelException((string) current($rolesInHerits->getMessages()));
294
            }
295
296
            return true;
297
        }
298
299
        return false;
300
    }
301
302
    /**
303
     * After update
304
     *
305
     * @return void
306
     */
307 2
    public function afterUpdate()
308
    {
309
        //if we deleted the role
310 2
        if ($this->is_deleted) {
311
            //delete
312 1
            foreach ($this->accesList as $access) {
313 1
                $access->softDelete();
314
            }
315
        }
316 2
    }
317
318
    /**
319
     * Check if role exists by its id
320
     * @param integer $role_id
321
     * @return Roles
322
     */
323 4
    public static function existsById(int $id): Roles
324
    {
325 4
        $role = self::getById($id);
326
327 4
        if (!is_object($role)) {
328
            throw new ModelException('Role does not exist');
329
        }
330
331 4
        return $role;
332
    }
333
}
334