UserRepository::validate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
namespace App\Repositories;
4
5
use App\Exceptions\RepositoryException;
6
use App\Exceptions\ValidationException;
7
use App\User;
8
use DB;
9
use Exception;
10
use Hash;
11
use Session;
12
use Validator;
13
use Carbon\Carbon;
14
15
class UserRepository extends Repository
16
{
17
    public function getModelName()
18
    {
19
        return 'App\User';
20
    }
21
22
    public function all()
23
    {
24
        try {
25
            return $this->model->fromGroup()->get();
26
        } catch (Exception $e) {
27
            throw new RepositoryException('Database error occurred', RepositoryException::DATABASE_ERROR);
28
        }
29
    }
30
31
    public function allByStatus($isActive)
32
    {
33
        if (!is_bool($isActive)) {
34
            throw new RepositoryException('Must be a boolean', RepositoryException::INCORRECT_PARAMETER);
35
        }
36
37
        try {
38
            return $this->model->fromGroup()->where('is_active', $isActive)->orderBy('role', 'DESC')->get();
39
        } catch (Exception $e) {
40
            throw new RepositoryException('Database error', RepositoryException::DATABASE_ERROR);
41
        }
42
    }
43
44
    public function get($id)
45
    {
46
        $this->validateID($id);
47
48
        try {
49
            $user = $this->model->fromGroup()->find($id);
50
        } catch (Exception $e) {
51
            throw new RepositoryException('Database error', RepositoryException::DATABASE_ERROR);
52
        }
53
54
        if (empty($user)) {
55
            throw new RepositoryException('User not found', RepositoryException::RESOURCE_NOT_FOUND);
56
        }
57
58
        return $user;
59
    }
60
61
    public function findActive($email)
62
    {
63
        if (is_null($email) || !is_string($email)) {
64
            throw new RepositoryException('Incorrect email address', RepositoryException::VALIDATION_FAILED);
65
        }
66
67
        try {
68
            $user = $this->model->activeGroup()
69
                ->where('email', '=', $email)
70
                ->where('users.is_active', true)
71
                ->first();
72
        } catch (Exception $e) {
73
            throw new RepositoryException('Database error occurred', RepositoryException::DATABASE_ERROR);
74
        }
75
76
        if (empty($user)) {
77
            throw new RepositoryException('User not found', RepositoryException::RESOURCE_NOT_FOUND);
78
        }
79
80
        return $user;
81
    }
82
83 View Code Duplication
    public function changeStatus($userId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
    {
85
        $user = $this->get($userId);
86
87
        try {
88
            if ($user->role == 'ADMN') {
89
                throw new RepositoryException('Cannot change status of administrator', RepositoryException::RESOURCE_DENIED);
90
            }
91
92
            $user->is_active = !$user->is_active;
93
            $user->save();
94
        } catch (Exception $e) {
95
            throw new RepositoryException('Database error', RepositoryException::DATABASE_ERROR);
96
        }
97
98
        return $user;
99
    }
100
101
    public function changeRole($userId)
102
    {
103
        $user = $this->get($userId);
104
105
        try {
106
107
            if ($user->role == 'ADMN') {
108
                throw new RepositoryException('Cannot change role of administrator', RepositoryException::RESOURCE_DENIED);
109
            }
110
111
            if ($user->role == 'USER') {
112
                $user->role = 'MNGR';
113
            } else {
114
                $user->role = 'USER';
115
            }
116
117
            $user->save();
118
119
        } catch (Exception $e) {
120
            throw new RepositoryException('Database error', RepositoryException::DATABASE_ERROR);
121
        }
122
123
        return $user;
124
    }
125
126
    public function store(array $data)
127
    {
128
        $this->validate($data);
129
130
        if ($data['role'] != 'USER' && $data['role'] != 'MNGR') {
131
            throw new RepositoryException('Invalid role name', RepositoryException::VALIDATION_FAILED);
132
        }
133
134
        $user = new User();
135
136
        $user->firstname = $data['firstname'];
0 ignored issues
show
Documentation introduced by
The property firstname does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
137
        $user->lastname = $data['lastname'];
0 ignored issues
show
Documentation introduced by
The property lastname does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
138
        $user->group_id = Session::get('groupID');
0 ignored issues
show
Documentation introduced by
The property group_id does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
139
        $user->email = $data['email'];
0 ignored issues
show
Documentation introduced by
The property email does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
140
        $user->password_hash = Hash::make($data['password']);
0 ignored issues
show
Documentation introduced by
The property password_hash does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
141
        $user->role = $data['role'];
0 ignored issues
show
Documentation introduced by
The property role does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
142
        $user->inscription_date = Carbon::now()->toDateTimeString();
0 ignored issues
show
Documentation introduced by
The property inscription_date does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
143
144
        try {
145
            $user->save();
146
        } catch (Exception $e) {
147
            throw new RepositoryException('Database error', RepositoryException::DATABASE_ERROR);
148
        }
149
150
        $user->id = DB::getPdo()->lastInsertId();
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<App\User>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
151
        return $user;
152
    }
153
154
    public function updateAccount($userId, array $userData)
155
    {
156
        $this->validateID($userId);
157
158
        $validator = Validator::make($userData, [
159
            'firstname'       => 'required|name',
160
            'lastname'        => 'required|name',
161
            'email'           => 'required|email',
162
            'password'        => 'password',
163
            'repeat_password' => 'required_with:password|same:password',
164
            'notes'           => '',
165
        ]);
166
167
        if ($validator->fails()) {
168
            throw new ValidationException($validator->errors());
169
        }
170
171
        try {
172
            $userAccount = $this->model->find($userId);
173
        } catch (Exception $e) {
174
            throw new RepositoryException('Could not retrieve user account', RepositoryException::DATABASE_ERROR);
175
        }
176
177
        $userAccount->firstname = $userData['firstname'];
178
        $userAccount->lastname = $userData['lastname'];
179
        $userAccount->notes = $userData['notes'];
180
181
        if (!empty($userData['password'])) {
182
            $userAccount->password_hash = Hash::make($userData['password']);
183
        }
184
185
        if ($userAccount->email != $userData['email']) {
186
187
            $emailValidator = Validator::make($userData, [
188
                'email' => 'unique:users,email'
189
            ]);
190
191
            if ($emailValidator->fails()) {
192
                throw new ValidationException($emailValidator->errors());
193
            }
194
195
            $userAccount->email = $userData['email'];
196
        }
197
198
        try {
199
            $userAccount->save();
200
        } catch (Exception $e) {
201
            throw new RepositoryException('Could not update account settings', RepositoryException::DATABASE_ERROR);
202
        }
203
    }
204
205 View Code Duplication
    public function softDelete($userId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
206
    {
207
        $user = $this->get($userId);
208
209
        if ($user->role == 'ADMN')
210
            throw new RepositoryException('Cannot delete administrator', RepositoryException::RESOURCE_DENIED);
211
212
        try {
213
            $user->delete();
214
        } catch (Exception $e) {
215
216
            throw new RepositoryException('Database error #' . $e->getCode(), RepositoryException::DATABASE_ERROR);
217
        }
218
219
        return $user;
220
    }
221
222
    public function validate(array $data)
223
    {
224
        $rules = User::$validationRules;
225
226
        $validator = Validator::make($data, $rules);
227
228
        if ($validator->fails()) {
229
            throw new ValidationException($validator->errors());
230
        }
231
    }
232
233
}