1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461:
<?php
/*
* This file is part of the Incipio package.
*
* (c) Théo FIDRY <theo.fidry@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace ApiBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Dunglas\ApiBundle\Annotation\Iri;
use FOS\UserBundle\Model\User as BaseUser;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Class User: user that have an account in the application.
*
* In this class, the term "organization" refers either to a Junior-Entreprise, Creation and such or a company.
*
* @ORM\Entity
* @UniqueEntity("username")
* @UniqueEntity("email")
*
* @author Théo FIDRY <theo.fidry@gmail.com>
*/
class User extends BaseUser
{
const TYPE_CONTRACTOR = 'TYPE_CONTRACTOR';
const TYPE_MEMBER = 'TYPE_MEMBER';
/**
* {@inheritdoc}
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
private $address;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
* @Groups({"user-read"})
*/
protected $createdAt;
/**
* {@inheritdoc}
*
* @Iri("https://schema.org/email")
* @Assert\Email
* @Assert\NotBlank
* @Groups({"user"})
*/
protected $email;
/**
* {@inheritdoc}
*
* @Assert\NotNull
* @Groups({"user"})
*
* @TODO: validation for boolean
*/
protected $enabled = false;
/**
* @var int
*
* @Iri("https://schema.org/name")
* @ORM\Column(type="smallint", nullable=true)
* @Assert\Range(
* min=1900,
* max=2100,
* minMessage="The ending school year must be a valid year.",
* maxMessage="The ending school year must be a valid year.",
* invalidMessage="The ending school year must be a valid year."
* )
* @Groups({"user"})
*/
private $endingSchoolYear;
/**
* @var string
*
* @Iri("https://schema.org/name")
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\NotBlank
* @Assert\Type("string")
* @Groups({"user"})
*
* @TODO: validation for username!
*/
protected $fullname;
/**
* @var string Professional email.
*
* @Iri("https://schema.org/email")
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\Email
* @Groups({"user"})
*/
private $organizationEmail;
/**
* @var string Professional email in lowercase for search and string comparison; cf emailCanonical & passwordCanonical
*
* @Iri("https://schema.org/email")
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\Email
* @Groups({"user-write"})
*/
private $organizationEmailCanonical;
private $phones;
/**
* {@inheritdoc}
*
* @var string
*
* @Groups({"user-write"})
* @TODO: validation for the password!
*/
protected $plainPassword;
/**
* {@inheritdoc}
*
* @Groups({"user"})
*/
protected $roles;
/**
* Validated via {@see ::validate()}.
*
* @var array
*
* @ORM\Column(type="array")
* @Groups({"user"})
*/
private $types = [];
/**
* @var StudentConvention
*
* @ORM\OneToOne(targetEntity="StudentConvention")
* @ORM\JoinColumn(referencedColumnName="reference")
* @Groups({"user"})
*/
private $studentConvention;
/**
* {@inheritdoc}
*
* @Assert\Type("string")
* @Groups({"user"})
*
* @TODO: validation for username!
*/
protected $username;
/**
* @var ArrayCollection|Job[] List of job for this user.
*
* @ORM\ManyToMany(targetEntity="Job", mappedBy="users")
* @Groups({"user"})
*
* @TODO: validation: may have no user
**/
protected $jobs;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
* @Groups({"user-read"})
*/
protected $updatedAt;
public function __construct()
{
parent::__construct();
$this->jobs = new ArrayCollection();
}
/**
* @param \DateTime $createdAt
*
* @return $this
*/
public function setCreatedAt(\DateTime $createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param int $endingSchoolYear
*
* @return $this
*/
public function setEndingSchoolYear($endingSchoolYear)
{
$this->endingSchoolYear = $endingSchoolYear;
return $this;
}
/**
* @return int|null
*/
public function getEndingSchoolYear()
{
return $this->endingSchoolYear;
}
/**
* @param string|null $fullname
*
* @return $this
*/
public function setFullname($fullname)
{
$this->fullname = $fullname;
return $this;
}
/**
* @return string|null
*/
public function getFullname()
{
return $this->fullname;
}
/**
* Adds Job. Will automatically update job's user too.
*
* @param Job $job
*
* @return $this
*/
public function addJob(Job $job)
{
// Check for duplicate
if (false === $this->jobs->contains($job)) {
$this->jobs->add($job);
}
// Ensure the relation is set for both entities
if (false === $job->getUsers()->contains($this)) {
$job->addUser($this);
}
return $this;
}
/**
* Removes job. Will automatically update job's user too.
*
* @param Job $job
*
* @return $this
*/
public function removeJob(Job $job)
{
$this->jobs->removeElement($job);
// Ensure the relation is unset for both entities
// The check must be done to avoid circular references
if (true === $job->getUsers()->contains($this)) {
$job->removeUser($this);
}
return $this;
}
/**
* @return ArrayCollection|Job[]
*/
public function getJobs()
{
return $this->jobs;
}
/**
* @param string $organizationEmail
*
* @return $this
*/
public function setOrganizationEmail($organizationEmail)
{
$this->organizationEmail = $organizationEmail;
return $this;
}
/**
* @return string|null
*/
public function getOrganizationEmail()
{
return $this->organizationEmail;
}
/**
* @param string $organizationEmailCanonical
*
* @return $this
*/
public function setOrganizationEmailCanonical($organizationEmailCanonical)
{
$this->organizationEmailCanonical = $organizationEmailCanonical;
return $this;
}
/**
* @return string|null
*/
public function getOrganizationEmailCanonical()
{
return $this->organizationEmailCanonical;
}
/**
* @param StudentConvention|null $studentConvention
*
* @return $this
*/
public function setStudentConvention(StudentConvention $studentConvention = null)
{
$this->studentConvention = $studentConvention;
return $this;
}
/**
* @return StudentConvention|null
*/
public function getStudentConvention()
{
return $this->studentConvention;
}
/**
* Add the given type if is not already present.
*
* @param string $type See ::getAllowedTypes() for valid values
*
* @return $this
*/
public function addType($type)
{
if (!in_array($type, $this->types)) {
$this->types[] = $type;
}
return $this;
}
/**
* See ::getAllowedTypes() for valid values.
*
* @param array $types
*
* @return $this
*/
public function setTypes(array $types)
{
$this->types = $types;
return $this;
}
/**
* @return array
*/
public function getTypes()
{
return $this->types;
}
/**
* @param \DateTime $updatedAt
*
* @return $this
*/
public function setUpdatedAt(\DateTime $updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* @return array Array of all valid values for the ::type property.
*/
public static function getAllowedTypes()
{
return [
'contractor' => self::TYPE_CONTRACTOR,
'member' => self::TYPE_MEMBER,
];
}
/**
* @param ExecutionContextInterface $context
*
* @Assert\Callback
*/
public function validate(ExecutionContextInterface $context)
{
$allowedTypes = array_flip($this->getAllowedTypes());
foreach ($this->getTypes() as $type) {
if (!isset($allowedTypes[$type])) {
$context
->buildViolation('This type is not a valid type')
->atPath('types')
->addViolation();
}
}
}
}