ProjectUserPolicy::before()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace App\Policies;
4
5
use App\Exceptions\MissingRequiredAttributeException;
6
use App\Http\Requests\Request;
7
use App\Models\Access\User\User;
8
use App\Models\Project;
9
use App\Models\ProjectUser;
10
use Illuminate\Auth\Access\HandlesAuthorization;
11
12
class ProjectUserPolicy
13
{
14
    use HandlesAuthorization;
15
16
    public function before($user): ?bool
17
    {
18
        if ($user->is_administrator) {
19
            return true;
20
        }
21
22
        return null;
23
    }
24
25
    /** Anyone can view a non-private project
26
     *  Only project members can view a private project.
27
     *
28
     * @param User        $user
29
     * @param ProjectUser $projectUser
30
     *
31
     * @return bool|null
32
     */
33
    public function view(User $user, ProjectUser $projectUser): ?bool
34
    {
35
        $project = $this->getProject($projectUser);
36
        if ($project) {
37
            if ($project->is_private && $user->isMemberOfProject($project)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $project->is_private of type null|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
38
                return true;
39
            }
40
            if (! $project->is_private) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $project->is_private of type null|integer is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
41
                return true;
42
            }
43
        }
44
45
        return null;
46
    }
47
48
    /**
49
     * @param User $user
50
     *
51
     * @return bool|null
52
     * @throws MissingRequiredAttributeException
53
     */
54
    public function create(User $user): ?bool
55
    {
56
        $project = Project::find(self::getProjectIdFromRoute());
57
58
        return $user->isAdminForProjectId($project->id);
59
    }
60
61
    public function update(User $user, ProjectUser $projectUser): ?bool
62
    {
63
        $project = $this->getProject($projectUser);
64
65
        return $user->isAdminForProjectId($project->id);
66
    }
67
68
    public function delete(User $user, ProjectUser $projectUser): ?bool
69
    {
70
        return $this->update($user, $projectUser);
71
    }
72
73
    /**
74
     * @param ProjectUser $projectUser
75
     *
76
     * @return Project|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|null|static|static[]
77
     * @throws MissingRequiredAttributeException
78
     */
79
    private function getProject(ProjectUser $projectUser)
80
    {
81
        if ($projectUser->exists) {
82
            $project = $projectUser->project;
83
        } else {
84
            $project = Project::find(self::getProjectIdFromRoute());
85
        }
86
87
        return $project;
88
    }
89
90
    private static function getProjectIdFromRoute()
91
    {
92
        if (request()->route()->parameter('project')) {
93
            return request()->route()->parameter('project');
94
        }
95
        if (request()->route()->parameter('project_id')) {
96
            return request()->route()->parameter('project_id');
97
        }
98
        throw new MissingRequiredAttributeException("A project reference is required and can't be found");
99
    }
100
}
101