Completed
Push — master ( a0b85b...774d12 )
by Wanderson
20:21
created

User::getEmail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Win\Authentication;
4
5
use Win\Mvc\Application;
6
use Win\Authentication\UserDAO;
7
use Local\Person\Person;
8
use Local\Person\PersonDAO;
9
use Win\Helper\Url;
10
use Win\Mvc\Block;
11
use Win\Mailer\Email;
12
use Win\File\Image;
13
use Win\Calendar\Date;
14
15
/**
16
 * Usuários do sistema
17
 */
18
class User {
19
20
	const ACCESS_DENIED = 0;
21
	const ACCESS_ALLOWED = 1;
22
	const ACCESS_ADMIN = 2;
23
24
	private static $passwordSalt = 'E50H%gDui#';
25
	private $id;
26
	private $isEnabled;
27
	private $isLogged;
28
	private $accessLevel;
29
	private $name;
30
	private $email;
31
	private $password;
32
	private $passwordHash;
33
	private $recoreryHash;
34
35
	/** @var Date */
36
	private $loginDate;
37
38
	/** @var Image */
39
	private $image;
40
41
	/** @var Group */
42
	private $group;
43
	private $groupId;
44
45
	/** @var Person */
46
	private $person;
47
48
	public function __construct() {
49
		$this->id = 0;
50
		$this->isEnabled = true;
51
		$this->isLogged = false;
52
		$this->accessLevel = self::ACCESS_DENIED;
53
		$this->name = '';
54
		$this->email = '';
55
		$this->password = '********';
56
		$this->passwordHash = '';
57
		$this->recoreryHash = null;
58
		$this->image = new Image();
59
		$this->image->setDirectory('data/upload/user');
60
		$this->loginDate = new Date('00/00/0000');
61
		$this->group = null;
62
		$this->groupId = 0;
63
		$this->person = null;
64
	}
65
66
	public function getId() {
67
		return $this->id;
68
	}
69
70
	public function isEnabled() {
71
		return $this->isEnabled;
72
	}
73
74
	public function isLogged() {
75
		return $this->isLogged;
76
	}
77
78
	public function getAccessLevel() {
79
		return $this->accessLevel;
80
	}
81
82
	/** @return boolean */
83
	public function isAdmin() {
84
		return ($this->accessLevel == self::ACCESS_ADMIN);
85
	}
86
87
	public function getGroup() {
88
		if (is_null($this->group)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
89
			// groupDAO
90
		}
91
		return $this->group;
92
	}
93
94
	public function getGroupId() {
95
		return $this->groupId;
96
	}
97
98
	/** @return Person */
99
	public function getPerson() {
100
		if (is_null($this->person)) {
101
			$pDAO = new PersonDAO();
102
			$this->person = $pDAO->fetchById($this->id);
103
		}
104
		return $this->person;
105
	}
106
107
	public function getName() {
108
		return $this->name;
109
	}
110
111
	public function getEmail() {
112
		return $this->email;
113
	}
114
115
	public function getPassword() {
116
		return $this->password;
117
	}
118
119
	public function getPasswordHash() {
120
		return $this->passwordHash;
121
	}
122
123
	public function getRecoreryHash() {
124
		return $this->recoreryHash;
125
	}
126
127
	public function getImage() {
128
		return $this->image;
129
	}
130
131
	/** @return Date */
132
	public function getLoginDate() {
133
		return $this->loginDate;
134
	}
135
136
	public function setId($id) {
137
		$this->id = (int) $id;
138
	}
139
140
	public function setEnabled($enabled) {
141
		$this->isEnabled = (boolean) $enabled;
142
	}
143
144
	public function setAccessLevel($accessLevel) {
145
		$this->accessLevel = (int) $accessLevel;
146
	}
147
148
	public function setGroup(Group $group) {
149
		$this->group = $group;
150
	}
151
152
	public function setGroupId($groupId) {
153
		$this->groupId = (int) $groupId;
154
	}
155
156
	public function setPerson(Person $person) {
157
		$this->person = $person;
158
	}
159
160
	public function setName($name) {
161
		$this->name = strClear($name);
162
	}
163
164
	public function setEmail($email) {
165
		$this->email = strClear($email);
166
	}
167
168
	public function setPassword($password) {
169
		$this->password = $password;
170
		$this->passwordHash = static::encryptPassword($password);
171
	}
172
173
	public function setPasswordHash($passwordHash) {
174
		$this->passwordHash = $passwordHash;
175
	}
176
177
	public function setRecoreryHash($recoreryHash) {
178
		$this->recoreryHash = $recoreryHash;
179
	}
180
181
	public function setLoginDate($loginDate) {
182
		$this->loginDate = $loginDate;
183
	}
184
185
	public function setImage($image) {
186
		$this->image = $image;
187
	}
188
189
	/**
190
	 * Tenta realizar login
191
	 * @return boolean
192
	 */
193
	public function login() {
194
		$filters = [
195
			'is_enabled = ?' => true,
196
			'access_level > ?' => 0,
197
			'email = ?' => $this->email,
198
			'password_hash = ?' => $this->passwordHash
199
		];
200
		$uDAO = new UserDAO();
201
		$user = $uDAO->fetch($filters);
0 ignored issues
show
Documentation introduced by
$filters is of type array<string,boolean|int...rd_hash = ?":"string"}>, but the function expects a array<integer,string>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
202
203
		if ($user->getId() > 0) {
204
			$this->setCurrentUser($user);
205
			$uDAO->updateLoginDate($user);
206
		}
207
		return $user->isLogged;
208
	}
209
210
	/** Realiza logout */
211
	public function logout() {
212
		unset($_SESSION['user']);
213
	}
214
215
	/** Objeto > Sessão */
216
	private function setCurrentUser(User $user) {
217
		$_SESSION['user'] = $user;
218
		$user->isLogged = true;
219
		$this->isLogged = true;
220
		$this->id = $user->getId();
221
		$this->accessLevel = $user->getAccessLevel();
222
		$this->name = $user->getName();
223
		$this->loginDate = $user->getLoginDate();
224
		$this->image = $user->getImage();
225
	}
226
227
	/** Objeto < Sessão */
228
	public static function getCurrentUser() {
229
		return (isset($_SESSION['user'])) ? $_SESSION['user'] : new User();
230
	}
231
232
	/** Obriga o usuário a se logar */
233
	public function requireLogin() {
234
		if (!$this->isLogged) {
235
			Url::instance()->redirect('login');
236
		}
237
	}
238
239
	/** Obriga o usuário a logar como ADMIN */
240
	public function requireAdmin() {
241
		$this->requireLogin();
242
		if ($this->getAccessLevel() != static::ACCESS_ADMIN) {
243
			Application::app()->errorPage(403);
244
		}
245
	}
246
247
	/**
248
	 * Envia link de recuperacao de senha via Email
249
	 * @return string | null
250
	 */
251
	public function sendRecoveryHash() {
252
		$filters = ['is_enabled = ?' => true, 'access_level > ?' => 0, 'email = ?' => $this->email];
253
		$uDAO = new UserDAO();
254
		$user = $uDAO->fetch($filters);
0 ignored issues
show
Documentation introduced by
$filters is of type array<string,boolean|int...,"email = ?":"string"}>, but the function expects a array<integer,string>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
255
256
		if ($user->getId() > 0) {
257
			$uDAO->updateRecoveryHash($user);
258
			$content = new Block('email/content/recovery-password', ['user' => $user]);
259
260
			$mail = new Email();
261
			$mail->setFrom(EMAIL_FROM, Application::app()->getName());
262
			$mail->setSubject('Recuperação de Senha');
263
			$mail->addAddress($user->getEmail(), $user->getName());
264
			$mail->setContent($content);
265
			return $mail->send();
266
		} else {
267
			return 'Este E-mail não está cadastrado no sistema.';
268
		}
269
	}
270
271
	/** Define os atributos que são salvos na SESSAO */
272
	public function __sleep() {
273
		return ['id', 'isEnabled', 'isLogged', 'accessLevel', 'name', 'email', 'image', 'loginDate', 'groupId'];
274
	}
275
276
	/**
277
	 * Adiciona maior segura na senha/ utilizar esta função ao inves de um simples md5
278
	 * @param string $password
279
	 */
280
	public static function encryptPassword($password) {
281
		return md5($password . static::$passwordSalt);
0 ignored issues
show
Bug introduced by
Since $passwordSalt is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $passwordSalt to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
282
	}
283
284
	/** @return boolean Retorna true se já existe este email no sistema */
285
	public function emailIsDuplicated() {
286
		$dao = new PersonDAO();
287
		return (boolean) $dao->numRows(['email = ?' => $this->email, 'person_id <> ?' => $this->id]);
288
	}
289
290
	/**
291
	 * Retorna uma senha aleatoria
292
	 * A senha tem sempre pelo menos: 1 caracter especial e 2 numeros;
293
	 * @param int $length
294
	 * @return string
295
	 */
296
	public static function generatePassword($length = 6) {
297
		$letters = str_shuffle('abcdefghijkmnopqrstwxyzABCDEFGHJKLMNPQRSTWXY');
298
		$numbers = str_shuffle('23456789');
299
		$specials = str_shuffle('@#&%');
300
301
		$password = substr($letters, 0, $length - 3)
302
				. substr($numbers, 0, 2)
303
				. substr($specials, 0, 1);
304
305
		return str_shuffle($password);
306
	}
307
308
}
309