Completed
Push — master ( aa55a0...981779 )
by Abdelrahman
03:08
created

UserRepository::hasAbilityTo()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Rinvex Fort Package.
7
 *
8
 * This source file is subject to The MIT License (MIT)
9
 * that is bundled with this package in the LICENSE file.
10
 *
11
 * Package: Rinvex Fort Package
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
namespace Rinvex\Fort\Repositories;
17
18
use Illuminate\Support\Str;
19
use Rinvex\Fort\Models\Role;
20
use Rinvex\Fort\Traits\HasRoles;
21
use Illuminate\Database\Eloquent\Model;
22
use Illuminate\Contracts\Hashing\Hasher;
23
use Illuminate\Contracts\Foundation\Application;
24
use Rinvex\Fort\Contracts\UserRepositoryContract;
25
use Rinvex\Fort\Contracts\AuthenticatableContract;
26
use Rinvex\Repository\Repositories\EloquentRepository;
27
28
class UserRepository extends EloquentRepository implements UserRepositoryContract
29
{
30
    use HasRoles;
31
32
    /**
33
     * The hasher implementation.
34
     *
35
     * @var \Illuminate\Contracts\Hashing\Hasher
36
     */
37
    protected $hasher;
38
39
    /**
40
     * create a new user repository instance.
41
     *
42
     * @param \Illuminate\Contracts\Foundation\Application $app
43
     *
44
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
45
     */
46
    public function __construct(Application $app, Hasher $hasher)
47
    {
48
        $this->setContainer($app)
49
             ->setHasher($hasher)
50
             ->setRepositoryId('rinvex.fort.user')
51
             ->setModel($app['config']['rinvex.fort.models.user']);
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function findByEmail($email)
58
    {
59
        return $this->findBy('email', $email);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function findByUsername($username)
66
    {
67
        return $this->findBy('username', $username);
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function findByToken($identifier, $token)
74
    {
75
        return $this->where($this->getAuthIdentifierName(), $identifier)
0 ignored issues
show
Documentation Bug introduced by
The method getAuthIdentifierName does not exist on object<Rinvex\Fort\Repositories\UserRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
76
                    ->where($this->getRememberTokenName(), $token)
0 ignored issues
show
Documentation Bug introduced by
The method getRememberTokenName does not exist on object<Rinvex\Fort\Repositories\UserRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
77
                    ->findFirst();
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function findByCredentials(array $credentials)
84
    {
85
        if (empty($credentials)) {
86
            return;
87
        }
88
89
        // First we will add each credential element to the query as a where clause.
90
        // Then we can execute the query and, if we found a user, return it in a
91
        // Eloquent User "model" that will be utilized by the Guard instances.
92
        $model = $this;
93
94
        foreach ($credentials as $key => $value) {
95
            if (! Str::contains($key, 'password')) {
96
                $model = $model->where($key, $value);
97
            }
98
        }
99
100
        return $model->findFirst();
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function updateRememberToken(AuthenticatableContract $user, $token)
107
    {
108
        $this->update($user, [$this->getRememberTokenName() => $token]);
0 ignored issues
show
Documentation Bug introduced by
The method getRememberTokenName does not exist on object<Rinvex\Fort\Repositories\UserRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function validateCredentials(AuthenticatableContract $user, array $credentials)
115
    {
116
        $plain = $credentials['password'];
117
118
        return $this->getHasher()->check($plain, $user->getAuthPassword());
119
    }
120
121
    /**
122
     * Gets the hasher implementation.
123
     *
124
     * @return \Illuminate\Contracts\Hashing\Hasher
125
     */
126
    public function getHasher()
127
    {
128
        return $this->hasher;
129
    }
130
131
    /**
132
     * Sets the hasher implementation.
133
     *
134
     * @param \Illuminate\Contracts\Hashing\Hasher $hasher
135
     *
136
     * @return $this
137
     */
138
    public function setHasher(Hasher $hasher)
139
    {
140
        $this->hasher = $hasher;
141
142
        return $this;
143
    }
144
145
    /**
146
     * Determine if the user may perform the given ability.
147
     *
148
     * @param \Illuminate\Database\Eloquent\Model                                     $model
149
     * @param string|array|\Rinvex\Fort\Models\Ability|\Illuminate\Support\Collection $role
0 ignored issues
show
Bug introduced by
There is no parameter named $role. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
150
     *
151
     * @return bool
152
     */
153
    public function hasAbilityTo(Model $model, $ability)
154
    {
155
        return $this->hasDirectAbility($model, $ability) || $this->hasAbilityViaRole($model, $ability);
156
    }
157
158
    /**
159
     * Get the menus for the given user.
160
     *
161
     * @param int  $modelId
162
     * @param bool $root
163
     *
164
     * @return mixed
165
     */
166
    public function menus($modelId, $root = true)
167
    {
168
        return $this->executeCallback(get_called_class(), __FUNCTION__, func_get_args(), function () use ($modelId, $root) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 124 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
169
            if (! is_int($modelId) || ! $model = $this->with(['abilities'])->find($modelId)) {
170
                return [];
171
            }
172
173
            $roleAbilities = null;
174
            $callback      = function ($item) {
175
                if (strpos($item, '.index') === false) {
176
                    return str_replace(strrchr($item, '.'), '.index', $item);
177
                } else {
178
                    return 'root';
179
                }
180
            };
181
182
            if (! $model instanceof Role) {
183
                $roleAbilities = $model->roles()->with(['abilities'])->get()->pluck('abilities')->flatten()->pluck('slug');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 123 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
184
            }
185
186
            $userAbilities = $model->abilities->pluck('slug')->merge($roleAbilities)->unique()->groupBy($callback)->toArray();
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
187
188
            return $root ? $userAbilities['root'] : $userAbilities;
189
        });
190
    }
191
}
192