Passed
Push — feature/permission-manager ( 41e93d )
by
unknown
09:00
created

HandlePermissions::afterSaveHandlePermissions()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 15
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 26
rs 8.8333
1
<?php
2
3
namespace A17\Twill\Repositories\Behaviors;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Support\Facades\Session;
7
use A17\Twill\Models\Permission;
8
9
trait HandlePermissions
10
{
11
    /**
12
     * Retrieve user-item permissions fields
13
     *
14
     * @param Model $object
0 ignored issues
show
Bug introduced by
The type A17\Twill\Repositories\Behaviors\Model 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...
15
     * @param array $fields
16
     * @return array
17
     */
18
    public function getFormFieldsHandlePermissions($object, $fields)
19
    {
20
        $moduleName = getModuleNameByModel($object);
21
22
        if (!$this->shouldProcessPermissions($moduleName)) {
23
            return $fields;
24
        }
25
26
        $userItemPermissions = twillModel('user')::notSuperAdmin()->get()->mapWithKeys(
27
            function ($user) use ($object, $moduleName) {
28
                $permissionName = $this->getUserItemPermissionName($user, $object, $moduleName);
29
30
                return ["user_{$user->id}_permission" => $permissionName];
31
            }
32
        )->toArray();
33
34
        $this->storePermissionFields($moduleName, $object, $userItemPermissions);
35
36
        return $fields + $userItemPermissions;
37
    }
38
39
    private function getUserItemPermissionName($user, $item, $moduleName)
40
    {
41
        if ($user->role->permissions()->global()->where('name', 'manage-modules')->first()) {
42
            return 'manage-item';
43
        }
44
45
        $allPermissionNames = collect([]);
46
47
        // Role-Module permission
48
        if ($modulePermission = $user->role->permissions()->ofModuleName($moduleName)->first()) {
49
            $allPermissionNames->push(str_replace('-module', '-item', $modulePermission->name));
50
        }
51
52
        // Group-Item permissions
53
        $userGroups = $user->groups()->where('is_everyone_group', false)->get();
54
        foreach($userGroups as $group) {
55
            if ($permission = $group->permissions()->ofItem($item)->first()) {
56
                $allPermissionNames->push($permission->name);
57
            }
58
        }
59
60
        // User-Item permission
61
        if ($itemPermission = $user->permissions()->ofItem($item)->first()) {
62
            $allPermissionNames->push($itemPermission->name);
63
        }
64
65
        return $this->getHighestItemPermissionName($allPermissionNames->filter());
66
    }
67
68
    private function getHighestItemPermissionName($permissionNames)
69
    {
70
        if (count($permissionNames) <= 1) {
71
            return $permissionNames[0] ?? '';
72
        }
73
74
        $itemScopes = collect(Permission::available(Permission::SCOPE_ITEM))
75
            ->reverse()
76
            ->mapWithKeys(function ($scope) { return [$scope => 0]; })
77
            ->toArray();
78
79
        foreach ($permissionNames as $name) {
80
            if (isset($itemScopes[$name])) {
81
                $itemScopes[$name]++;
82
            }
83
        }
84
85
        foreach ($itemScopes as $scope => $count) {
86
            if ($count > 0) {
87
                return $scope;
88
            }
89
        }
90
91
        return '';
92
    }
93
94
    /**
95
     * Function executed after save on module form
96
     *
97
     * @param Model $object
98
     * @param array $fields
99
     */
100
    public function afterSaveHandlePermissions($object, $fields)
101
    {
102
        $moduleName = getModuleNameByModel($object);
103
104
        if (!$this->shouldProcessPermissions($moduleName)) {
105
            return;
106
        }
107
108
        $oldItemPermissions = $this->recallPermissionFields($moduleName, $object);
109
110
        foreach ($fields as $key => $value) {
111
            if (!Str::endsWith($key, '_permission')) {
112
                continue;
113
            }
114
115
            if (isset($oldItemPermissions[$key]) && $oldItemPermissions[$key] === $value) {
116
                continue;
117
            }
118
119
            $userId = explode('_', $key)[1];
120
            $user = twillModel('user')::find($userId);
121
122
            if ($value) {
123
                $user->grantModuleItemPermission($value, $object);
124
            } else {
125
                $user->revokeModuleItemAllPermissions($object);
126
            }
127
        }
128
    }
129
130
    private function shouldProcessPermissions($moduleName)
131
    {
132
        return config('twill.enabled.permissions-management')
133
            && config('twill.permissions.level') === 'roleGroupItem'
134
            && isPermissionableModule($moduleName);
135
    }
136
137
    private function storePermissionFields($moduleName, $object, $permissionFields)
138
    {
139
        Session::put("{$moduleName}_{$object->id}_item_permissions", $permissionFields);
140
    }
141
142
    private function recallPermissionFields($moduleName, $object)
143
    {
144
        return Session::get("{$moduleName}_{$object->id}_item_permissions") ?: [];
145
    }
146
}
147