Roles::getSource()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Canvas\Models;
5
6
use Baka\Database\Exception\ModelNotFoundException;
0 ignored issues
show
Bug introduced by
The type Baka\Database\Exception\ModelNotFoundException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Phalcon\Di;
8
use Phalcon\Validation;
0 ignored issues
show
Bug introduced by
The type Phalcon\Validation was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Phalcon\Validation\Validator\PresenceOf;
0 ignored issues
show
Bug introduced by
The type Phalcon\Validation\Validator\PresenceOf was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Phalcon\Validation\Validator\StringLength;
0 ignored issues
show
Bug introduced by
The type Phalcon\Validation\Validator\StringLength was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Phalcon\Acl\Role as AclRole;
0 ignored issues
show
Bug introduced by
The type Phalcon\Acl\Role was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Canvas\Http\Exception\InternalServerErrorException;
13
use Canvas\Http\Exception\UnprocessableEntityException;
14
use Phalcon\Validation\Validator\Uniqueness;
15
16
/**
17
 * Class Roles.
18
 *
19
 * @package Canvas\Models
20
 *
21
 * @property AccesList $accesList
22
 * @property \Phalcon\Di $di
23
 */
24
class Roles extends AbstractModel
25
{
26
    /**
27
     *
28
     * @var integer
29
     */
30
    public $id;
31
32
    /**
33
     *
34
     * @var string
35
     */
36
    public $name;
37
38
    /**
39
     *
40
     * @var string
41
     */
42
    public $description;
43
44
    /**
45
     *
46
     * @var integer
47
     */
48
    public $scope;
49
50
    /**
51
     *
52
     * @var integer
53
     */
54
    public $companies_id;
55
56
    /**
57
     *
58
     * @var int
59
     */
60
    public $apps_id;
61
62
    /**
63
     *
64
     * @var string
65
     */
66
    public $created_at;
67
68
    /**
69
     *
70
     * @var string
71
     */
72
    public $updated_at;
73
74
    /**
75
     *
76
     * @var integer
77
     */
78
    public $is_deleted;
79
80
    /**
81
     * Default ACL company.
82
     *
83
     */
84
    const DEFAULT_ACL_COMPANY_ID = 1;
85
    const DEFAULT_ACL_APP_ID = 1;
86
    const DEFAULT = 'Admins';
87
88
    /**
89
     * Initialize method for model.
90
     */
91
    public function initialize()
92
    {
93
        $this->setSource('roles');
94
95
        $this->hasMany(
96
            'id',
97
            'Canvas\Models\AccessList',
98
            'roles_id',
99
            ['alias' => 'accesList']
100
        );
101
    }
102
103
    /**
104
     * Validations and business logic.
105
     */
106
    public function validation()
107
    {
108
        $validator = new Validation();
109
110
        $validator->add(
111
            'name',
112
            new PresenceOf([
113
                'field' => 'name',
114
                'required' => true,
115
            ])
116
        );
117
118
        $validator->add(
119
            'description',
120
            new PresenceOf([
121
                'field' => 'description',
122
                'required' => true,
123
            ])
124
        );
125
126
        $validator->add(
127
            'name',
128
            new StringLength([
129
                'max' => 32,
130
                'messageMinimum' => _('Role Name. Maxium 32 characters.'),
131
            ])
132
        );
133
134
        $validator->add(
135
            ['name', 'companies_id', 'apps_id'],
136
            new Uniqueness(
137
                [
138
                    'message' => 'Can\'t have 2 roles with the same name - ' . $this->name
139
                ]
140
            )
141
        );
142
143
        return $this->validate($validator);
144
    }
145
146
    /**
147
     * Returns table name mapped in the model.
148
     *
149
     * @return string
150
     */
151
    public function getSource(): string
152
    {
153
        return 'roles';
154
    }
155
156
    /**
157
     * Check if the role existe in the db.
158
     *
159
     * @param AclRole $role
160
     * @return int
161
     */
162
    public static function exist(AclRole $role): int
163
    {
164
        $companyId = Di::getDefault()->getAcl()->getCompany()->getId();
165
166
        return self::count([
167
            'conditions' => 'name = ?0 AND companies_id = ?1 AND apps_id = ?2',
168
            'bind' => [
169
                $role->getName(),
170
                $companyId,
171
                Di::getDefault()->getAcl()->getApp()->getId()
172
            ]
173
        ]);
174
    }
175
176
    /**
177
     * check if this string is already a role
178
     * whats the diff with exist or why not merge them? exist uses the alc object and only check
179
     * with your current app, this also check with de defautl company ap.
180
     *
181
     * @param string $roleName
182
     * @return boolean
183
     */
184
    public static function isRole(string $roleName) : bool
185
    {
186
        $companyId = Di::getDefault()->getAcl()->getCompany()->getId();
187
188
        return (bool) self::count([
189
            'conditions' => 'name = ?0 AND apps_id in (?1, ?3) AND companies_id in (?2, ?3)',
190
            'bind' => [
191
                $roleName,
192
                Di::getDefault()->getAcl()->getApp()->getId(),
193
                $companyId,
194
                Apps::CANVAS_DEFAULT_APP_ID
195
            ]
196
        ]);
197
    }
198
199
    /**
200
     * Get the entity by its name.
201
     *
202
     * @param string $name
203
     * @return Roles
204
     */
205
    public static function getByName(string $name): Roles
206
    {
207
        $companyId = Di::getDefault()->getAcl()->getCompany()->getId();
208
209
        $role = self::findFirst([
210
            'conditions' => 'name = ?0 AND apps_id in (?1, ?3) AND companies_id in (?2, ?3) AND is_deleted = 0',
211
            'bind' => [
212
                $name,
213
                Di::getDefault()->getAcl()->getApp()->getId(),
214
                $companyId,
215
                Apps::CANVAS_DEFAULT_APP_ID
216
            ],
217
            'order' => 'apps_id DESC'
218
        ]);
219
220
        if (!is_object($role)) {
221
            throw new UnprocessableEntityException(
222
                _('Roles ' . $name . ' not found on this app ' . Di::getDefault()->getAcl()->getApp()->getId() . ' AND Company ' . Di::getDefault()->getUserData()->currentCompanyId())
223
            );
224
        }
225
226
        return $role;
227
    }
228
229
    /**
230
     * Get the entity by its name.
231
     *
232
     * @param string $name
233
     * @return Roles
234
     */
235
    public static function getById(int $id): Roles
236
    {
237
        $companyId = Di::getDefault()->getAcl()->getCompany()->getId();
238
239
        return self::findFirstOrFail([
240
            'conditions' => 'id = ?0 AND companies_id in (?1, ?2) AND apps_id in (?3, ?4) AND is_deleted = 0',
241
            'bind' => [
242
                $id,
243
                $companyId,
244
                self::DEFAULT_ACL_COMPANY_ID,
245
                Di::getDefault()->getAcl()->getApp()->getId(),
246
                Apps::CANVAS_DEFAULT_APP_ID
247
            ],
248
            'order' => 'apps_id DESC'
249
        ]);
250
    }
251
252
    /**
253
     * Get the Role by it app name.
254
     *
255
     * @param string $role
256
     * @return Roles
257
     */
258
    public static function getByAppName(string $role, Companies $company): Roles
259
    {
260
        //echeck if we have a dot , taht means we are sending the specific app to use
261
        if (strpos($role, '.') === false) {
262
            throw new InternalServerErrorException('ACL - We are expecting the app for this role');
263
        }
264
265
        $appRole = explode('.', $role);
266
        $role = $appRole[1];
267
        $appName = $appRole[0];
268
269
        //look for the app and set it
270
        if (!$app = Apps::getACLApp($appName)) {
271
            throw new InternalServerErrorException('ACL - No app found for this role');
272
        }
273
274
        return self::findFirstOrFail([
275
            'conditions' => 'name = ?0 and apps_id in (?1, ?2) AND companies_id in (?3 , ?4)',
276
            'bind' => [
277
                $role,
278
                $app->getId(),
279
                self::DEFAULT_ACL_APP_ID,
280
                $company->getId(),
281
                self::DEFAULT_ACL_COMPANY_ID
282
            ],
283
            'order' => 'apps_id DESC'
284
        ]);
285
    }
286
287
    /**
288
     * Duplicate a role with it access list.
289
     *
290
     * @return Roles
291
     */
292
    public function copy(): Roles
293
    {
294
        $accesList = $this->accesList;
295
296
        //remove id to create new record
297
        $this->name .= 'Copie';
298
        $this->scope = 1;
299
        $this->id = null;
300
        $this->companies_id = $this->di->getUserData()->currentCompanyId();
301
        $this->apps_id = $this->di->getApp()->getId();
302
        $this->save();
303
304
        foreach ($accesList as $access) {
305
            $copyAccessList = new AccessList();
306
            $copyAccessList->apps_id = $this->apps_id;
307
            $copyAccessList->roles_id = $this->getId();
308
            $copyAccessList->roles_name = $this->name;
309
            $copyAccessList->resources_name = $access->resources_name;
310
            $copyAccessList->access_name = $access->access_name;
311
            $copyAccessList->allowed = $access->allowed;
312
            $copyAccessList->create();
313
        }
314
315
        return $this;
316
    }
317
318
    /**
319
     * Add inherit to a given role.
320
     *
321
     * @param string $roleName
322
     * @param string $roleToInherit
323
     * @return boolean
324
     */
325
    public static function addInherit(string $roleName, string $roleToInherit)
326
    {
327
        $role = self::findFirstByName($roleName);
328
329
        if (!is_object($role)) {
330
            throw new UnprocessableEntityException("Role '{$roleName}' does not exist in the role list");
331
        }
332
333
        $inheritExist = RolesInherits::count([
334
            'conditions' => 'roles_name = ?0 and roles_inherit = ?1',
335
            'bind' => [$role->name, $roleToInherit]
336
        ]);
337
338
        if (!$inheritExist) {
339
            $rolesInHerits = new RolesInherits();
340
            $rolesInHerits->roles_name = $role->name;
341
            $rolesInHerits->roles_id = $role->getId();
342
            $rolesInHerits->roles_inherit = (int) $roleToInherit;
343
344
            if (!$rolesInHerits->save()) {
345
                throw new UnprocessableEntityException((string) current($rolesInHerits->getMessages()));
346
            }
347
348
            return true;
349
        }
350
351
        return false;
352
    }
353
354
    /**
355
     * After update.
356
     *
357
     * @return void
358
     */
359
    public function afterUpdate()
360
    {
361
        //if we deleted the role
362
        if ($this->is_deleted) {
363
            //delete
364
            foreach ($this->accesList as $access) {
365
                $access->softDelete();
366
            }
367
        }
368
    }
369
370
    /**
371
     * Check if role exists by its id.
372
     * @param integer $role_id
373
     * @return Roles
374
     */
375
    public static function existsById(int $id): Roles
376
    {
377
        $role = self::getById($id);
378
379
        if (!is_object($role)) {
380
            throw new ModelNotFoundException('Role does not exist');
381
        }
382
383
        return $role;
384
    }
385
386
    /**
387
     * Assign the default app role to a given user.
388
     *
389
     * @param Users $user
390
     * @return bool
391
     */
392
    public static function assignDefault(Users $user): bool
393
    {
394
        $apps = Di::getDefault()->getApp();
395
        $userRoles = UserRoles::findFirst([
396
            'conditions' => 'users_id = ?0 AND apps_id = ?1 AND companies_id = ?2 AND is_deleted = 0',
397
            'bind' => [
398
                $user->getId(),
399
                $apps->getId(),
400
                $user->getDefaultCompany()->getId()
401
            ]
402
        ]);
403
404
        if (!is_object($userRoles)) {
405
            $userRole = new UserRoles();
406
            $userRole->users_id = $user->getId();
407
            $userRole->roles_id = Roles::getByName(Roles::DEFAULT)->getId();
408
            $userRole->apps_id = $apps->getId();
409
            $userRole->companies_id = $user->getDefaultCompany()->getId();
410
            return $userRole->saveOrFail();
411
        }
412
413
        return true;
414
    }
415
}
416