PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/Model/User.php

https://github.com/dunglas/DoctrineUserBundle
PHP | 603 lines | 253 code | 74 blank | 276 comment | 7 complexity | 921654f5c041781ec1e9fbac286b4ee6 MD5 | raw file
  1. <?php
  2. /**
  3. * (c) Thibault Duplessis <thibault.duplessis@gmail.com>
  4. *
  5. * This source file is subject to the MIT license that is bundled
  6. * with this source code in the file LICENSE.
  7. */
  8. namespace Bundle\DoctrineUserBundle\Model;
  9. use Doctrine\Common\Collections\Collection;
  10. use Doctrine\Common\Collections\ArrayCollection;
  11. use Symfony\Component\Security\User\AdvancedAccountInterface;
  12. /**
  13. * Storage agnostic user object
  14. * Has validator annotation, but database mapping must be done in a subclass.
  15. */
  16. abstract class User implements AdvancedAccountInterface
  17. {
  18. protected $id;
  19. /**
  20. * @validation:Validation({
  21. * @validation:NotBlank(message="Please enter a username", groups="Registration"),
  22. * @validation:MinLength(limit=2, message="The username is too short", groups="Registration"),
  23. * @validation:MaxLength(limit=255, message="The username is too long", groups="Registration")
  24. * })
  25. * @var string
  26. */
  27. protected $username;
  28. /**
  29. * @var string
  30. */
  31. protected $usernameLower;
  32. /**
  33. * @validation:Validation({
  34. * @validation:NotBlank(message="Please enter an email", groups="Registration"),
  35. * @validation:Email(message="This is not a valid email", groups="Registration"),
  36. * @validation:MaxLength(limit=255, message="The email is too long", groups="Registration")
  37. * })
  38. * @var string
  39. */
  40. protected $email;
  41. /**
  42. * @validation:AssertType(type="boolean")
  43. * @var boolean
  44. */
  45. protected $isActive;
  46. /**
  47. * @validation:AssertType(type="boolean")
  48. * @var boolean
  49. */
  50. protected $isSuperAdmin;
  51. /**
  52. * @validation:Validation({
  53. * @validation:NotBlank(message="Please enter a password", groups="Registration"),
  54. * @validation:MinLength(limit=2, message="The password is too short", groups="Registration"),
  55. * @validation:MaxLength(limit=255, message="The password is too long", groups="Registration")
  56. * })
  57. * @var string
  58. */
  59. protected $password;
  60. /**
  61. * @var string
  62. */
  63. protected $passwordHash;
  64. /**
  65. * @var string
  66. */
  67. protected $algorithm;
  68. /**
  69. * @var string
  70. */
  71. protected $salt;
  72. /**
  73. * @var \DateTime
  74. */
  75. protected $createdAt;
  76. /**
  77. * @var \DateTime
  78. */
  79. protected $updatedAt;
  80. /**
  81. * @var \DateTime
  82. */
  83. protected $lastLogin;
  84. /**
  85. * Random string sent to the user email adress in order to verify it
  86. *
  87. * @var string
  88. */
  89. protected $confirmationToken;
  90. /**
  91. * Random string stored in client cookie to enable automatic login
  92. *
  93. * @var string
  94. */
  95. protected $rememberMeToken;
  96. /**
  97. * @var Collection
  98. */
  99. protected $groups;
  100. /**
  101. * @var Collection
  102. */
  103. protected $permissions;
  104. public function __construct()
  105. {
  106. $this->algorithm = 'sha1';
  107. $this->salt = md5(uniqid() . rand(100000, 999999));
  108. $this->confirmationToken = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
  109. $this->renewRememberMeToken();
  110. $this->isActive = false;
  111. $this->isSuperAdmin = false;
  112. }
  113. /**
  114. * Return the user roles
  115. * Implements AccountInterface
  116. *
  117. * @return array The roles
  118. **/
  119. public function getRoles()
  120. {
  121. return array();
  122. }
  123. /**
  124. * Removes sensitive data from the user.
  125. * Implements AccountInterface
  126. */
  127. public function eraseCredentials()
  128. {
  129. }
  130. /**
  131. * Checks whether the user's account has expired.
  132. * Implements AdvancedAccountInterface
  133. *
  134. * @return Boolean true if the user's account is non expired, false otherwise
  135. */
  136. public function isAccountNonExpired()
  137. {
  138. return true;
  139. }
  140. /**
  141. * Checks whether the user is locked.
  142. * Implements AdvancedAccountInterface
  143. *
  144. * @return Boolean true if the user is not locked, false otherwise
  145. */
  146. public function isAccountNonLocked()
  147. {
  148. return true;
  149. }
  150. /**
  151. * Checks whether the user's credentials (password) has expired.
  152. * Implements AdvancedAccountInterface
  153. *
  154. * @return Boolean true if the user's credentials are non expired, false otherwise
  155. */
  156. public function isCredentialsNonExpired()
  157. {
  158. return true;
  159. }
  160. /**
  161. * Checks whether the user is enabled.
  162. * Implements AdvancedAccountInterface
  163. *
  164. * @return Boolean true if the user is enabled, false otherwise
  165. */
  166. public function isEnabled()
  167. {
  168. return $this->getIsActive();
  169. }
  170. /**
  171. * Return the user unique id
  172. *
  173. * @return mixed
  174. */
  175. public function getId()
  176. {
  177. return $this->id;
  178. }
  179. /**
  180. * @return string
  181. */
  182. public function getUsername()
  183. {
  184. return $this->username;
  185. }
  186. /**
  187. * @param string $username
  188. */
  189. public function setUsername($username)
  190. {
  191. $this->username = $username;
  192. $this->usernameLower = static::strtolower($username);
  193. }
  194. /**
  195. * Get the username in lowercase used in search and sort queries
  196. *
  197. * @return string
  198. **/
  199. public function getUsernameLower()
  200. {
  201. return $this->usernameLower;
  202. }
  203. /**
  204. * Get email
  205. * @return string
  206. */
  207. public function getEmail()
  208. {
  209. return $this->email;
  210. }
  211. /**
  212. * Set email
  213. * @param string
  214. * @return null
  215. */
  216. public function setEmail($email)
  217. {
  218. $this->email = static::strtolower($email);
  219. }
  220. /**
  221. * Hashed password
  222. * @return string
  223. */
  224. public function getPassword()
  225. {
  226. return $this->passwordHash;
  227. }
  228. /**
  229. * Return the salt used to hash the password
  230. *
  231. * @return string The salt
  232. **/
  233. public function getSalt()
  234. {
  235. return $this->salt;
  236. }
  237. /**
  238. * @param string $password
  239. */
  240. public function setPassword($password)
  241. {
  242. if (empty($password)) {
  243. $this->password = null;
  244. }
  245. $this->password = $password;
  246. $this->passwordHash = $this->hashPassword($password);
  247. }
  248. /**
  249. * @param string $algorithm
  250. */
  251. public function setAlgorithm($algorithm)
  252. {
  253. $this->algorithm = $algorithm;
  254. }
  255. /**
  256. * @return bool
  257. */
  258. public function getIsActive()
  259. {
  260. return $this->isActive;
  261. }
  262. /**
  263. * @param bool $isActive
  264. */
  265. public function setIsActive($isActive)
  266. {
  267. $this->isActive = $isActive;
  268. }
  269. /**
  270. * @return bool
  271. */
  272. public function getIsSuperAdmin()
  273. {
  274. return $this->isSuperAdmin;
  275. }
  276. /**
  277. * @param bool $isActive
  278. */
  279. public function setIsSuperAdmin($isSuperAdmin)
  280. {
  281. $this->isSuperAdmin = $isSuperAdmin;
  282. }
  283. /**
  284. * @return \DateTime
  285. */
  286. public function getCreatedAt()
  287. {
  288. return $this->createdAt;
  289. }
  290. /**
  291. * @return \DateTime
  292. */
  293. public function getUpdatedAt()
  294. {
  295. return $this->updatedAt;
  296. }
  297. /**
  298. * @return \DateTime
  299. */
  300. public function getLastLogin()
  301. {
  302. return $this->lastLogin;
  303. }
  304. /**
  305. * @param \DateTime $time
  306. */
  307. public function setLastLogin(\DateTime $time)
  308. {
  309. $this->lastLogin = $time;
  310. }
  311. /**
  312. * Returns whether or not the given password is valid.
  313. *
  314. * @param string $password
  315. * @return boolean
  316. */
  317. public function checkPassword($password)
  318. {
  319. return $this->passwordHash === $this->hashPassword($password);
  320. }
  321. public function __toString()
  322. {
  323. return (string) $this->getUsername();
  324. }
  325. public function incrementCreatedAt()
  326. {
  327. if (null === $this->createdAt) {
  328. $this->createdAt = new \DateTime();
  329. }
  330. $this->updatedAt = new \DateTime();
  331. }
  332. public function incrementUpdatedAt()
  333. {
  334. $this->updatedAt = new \DateTime();
  335. }
  336. /**
  337. * @return string hashed password
  338. */
  339. protected function hashPassword($password)
  340. {
  341. return hash_hmac($this->algorithm, $password, $this->salt);
  342. }
  343. /**
  344. * Get confirmationToken
  345. * @return string
  346. */
  347. public function getConfirmationToken()
  348. {
  349. return $this->confirmationToken;
  350. }
  351. /**
  352. * Set confirmationToken
  353. * @param string
  354. * @return null
  355. */
  356. public function setConfirmationToken($confirmationToken)
  357. {
  358. $this->confirmationToken = $confirmationToken;
  359. }
  360. /**
  361. * Get rememberMeToken
  362. * @return string
  363. */
  364. public function getRememberMeToken()
  365. {
  366. return $this->rememberMeToken;
  367. }
  368. /**
  369. * Renew the rememberMeToken
  370. * @return null
  371. */
  372. public function renewRememberMeToken()
  373. {
  374. $this->rememberMeToken = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
  375. }
  376. /**
  377. * Get groups granted to the user
  378. *
  379. * @return Collection
  380. */
  381. public function getGroups()
  382. {
  383. return $this->groups ?: $this->groups = new ArrayCollection();
  384. }
  385. /**
  386. * Gets the name of the groups which includes the user
  387. *
  388. * @return array
  389. */
  390. public function getGroupNames()
  391. {
  392. $names = array();
  393. foreach ($this->getGroups() as $group) {
  394. $names[] = $group->getName();
  395. }
  396. return $names;
  397. }
  398. /**
  399. * Indicates whether the user belongs to the specified group or not
  400. *
  401. * @param string $name Name of the group
  402. * @return boolean
  403. */
  404. public function hasGroup($name)
  405. {
  406. return in_array($name, $this->getGroupNames());
  407. }
  408. /**
  409. * Add a group to the user groups
  410. *
  411. * @param Group $group
  412. * @return null
  413. **/
  414. public function addGroup(Group $group)
  415. {
  416. if (!$this->getGroups()->contains($group)) {
  417. $this->getGroups()->add($group);
  418. }
  419. }
  420. /**
  421. * Remove a group from the user groups
  422. *
  423. * @param Group $group
  424. * @return null
  425. **/
  426. public function removeGroup(Group $group)
  427. {
  428. if ($this->getGroups()->contains($group)) {
  429. $this->getGroups()->remove($group);
  430. }
  431. }
  432. /**
  433. * Get permissions granted to the user
  434. *
  435. * @return Collection
  436. */
  437. public function getPermissions()
  438. {
  439. return $this->permissions ?: $this->permissions = new ArrayCollection();
  440. }
  441. /**
  442. * Gets the name of the permissions granted to the user
  443. *
  444. * @return array
  445. */
  446. public function getPermissionNames()
  447. {
  448. $names = array();
  449. foreach ($this->getPermissions() as $permission) {
  450. $names[] = $permission->getName();
  451. }
  452. return $names;
  453. }
  454. /**
  455. * Get all permissions, including user groups permissions
  456. *
  457. * @return ArrayCollection
  458. */
  459. public function getAllPermissions()
  460. {
  461. $permissions = $this->getPermissions()->toArray();
  462. foreach ($this->getGroups() as $group) {
  463. $permissions = array_merge($permissions, $group->getPermissions()->toArray());
  464. }
  465. return new ArrayCollection(array_unique($permissions));
  466. }
  467. /**
  468. * Get all permission names, including user groups permissions
  469. *
  470. * @return array
  471. */
  472. public function getAllPermissionNames()
  473. {
  474. $names = array();
  475. foreach ($this->getAllPermissions() as $permission) {
  476. $names[] = $permission->getName();
  477. }
  478. return $names;
  479. }
  480. /**
  481. * Indicates whether the specified permission is granted to the user or not
  482. *
  483. * @param string $name Name of the permission
  484. * @return boolean
  485. */
  486. public function hasPermission($name)
  487. {
  488. return in_array($name, $this->getAllPermissionNames());
  489. }
  490. /**
  491. * Add a permission to the user permissions
  492. *
  493. * @param Permission $permission
  494. * @return null
  495. **/
  496. public function addPermission(Permission $permission)
  497. {
  498. if (!$this->getPermissions()->contains($permission)) {
  499. $this->getPermissions()->add($permission);
  500. }
  501. }
  502. /**
  503. * Remove a permission from the user permissions
  504. *
  505. * @param Permission $permission
  506. * @return null
  507. **/
  508. public function removePermission(Permission $permission)
  509. {
  510. if ($this->getPermissions()->contains($permission)) {
  511. $this->getPermissions()->remove($permission);
  512. }
  513. }
  514. /**
  515. * Tell if the the given user is this user
  516. * Useful when not hydrating all fields.
  517. *
  518. * @param User $user
  519. * @return boolean
  520. */
  521. public function is(User $user = null)
  522. {
  523. return null !== $user && $this->getUsername() === $user->getUsername();
  524. }
  525. public static function strtolower($string)
  526. {
  527. return extension_loaded('mbstring') ? mb_strtolower($string) : strtolower($string);
  528. }
  529. }