<?php
namespace Bidcoz\Bundle\CoreBundle\Entity;
use Bidcoz\Bundle\CoreBundle\Entity\Auction\WatchListItem;
use Bidcoz\Bundle\CoreBundle\Entity\Contact\CompanyMember;
use Bidcoz\Bundle\CoreBundle\Entity\PaymentGateway\PaymentGateway;
use Bidcoz\Bundle\CoreBundle\Entity\Terms\UserTerms;
use Bidcoz\Bundle\CoreBundle\Util\TextManipulator;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use FOS\UserBundle\Util\Canonicalizer;
use JMS\Serializer\Annotation as Serialize;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="UserRepository")
* @ORM\Table(name="users")
* @Serialize\ExclusionPolicy("all")
* @UniqueEntity("email", message="")
* @ORM\AttributeOverrides({
* @ORM\AttributeOverride(name="password",
* column=@ORM\Column(
* nullable=true
* )
* ),
* })
*/
class User extends BaseUser
{
public const NOTIFICATION_EMAIL = 'email';
public const NOTIFICATION_SMS = 'sms';
public const DEFAULT_TIMEZONE = 'America/Chicago';
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Serialize\Expose
* @Serialize\Groups({"Default", "API"})
*/
protected $id;
/**
* @ORM\Column(name="fname", length=50)
* @Assert\NotBlank(groups={"Registration", "Profile"})
* @Assert\Length(min=1, max=50, groups={"Registration", "Profile"})
* @Serialize\Expose
* @Serialize\SerializedName("firstName")
*/
protected $firstName;
/**
* @ORM\Column(name="lname", length=50)
* @Assert\NotBlank(groups={"Registration", "Profile"})
* @Assert\Length(min=1, max=50)
* @Serialize\Expose
* @Serialize\SerializedName("lastName")
*/
protected $lastName;
/**
* @Serialize\Expose
* @Serialize\SerializedName("email")
* @Serialize\Groups({"Default", "API"})
*/
protected $emailCanonical;
/**
* @ORM\Embedded(class= "Address", columnPrefix=false)
* @Assert\Valid
*/
protected $address;
/**
* @ORM\Column(name="phone", length=42, nullable=true)
* @Assert\Expression(
* "this.isPhoneValidForSMS() or !this.getSMSOptIn()",
* message="Please provide a valid mobile phone number!",
* groups={"Registration", "Profile"}
* )
*/
protected $phone;
/**
* @ORM\Column(name="skip_mobile", type="boolean")
* @Assert\NotNull(groups={"Registration", "Profile"})
*/
protected $skipMobile = false;
/**
* @ORM\Column(name="sms_opt_in", type="boolean")
* @Assert\NotNull(groups={"Registration", "Profile"})
*/
protected bool $smsOptIn = true;
/**
* @ORM\Column(name="timezone", length=50)
* @Assert\NotBlank(groups={"Registration", "Profile"}, message="Please choose your timezone")
*/
protected $timezone = self::DEFAULT_TIMEZONE;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Auction\WatchListItem", mappedBy="user")
*/
protected $watchList;
/**
* @ORM\OneToMany(targetEntity="OrganizationAdmin", mappedBy="user")
*/
protected $orgAdmins;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Ticket\Ticket", mappedBy="user")
*/
protected $tickets;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\CreditCard", mappedBy="user")
*/
protected $creditCards;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Ticket\TicketGroup", mappedBy="owner")
*/
protected $ticketGroups;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Purchase\Purchase", mappedBy="user")
*/
protected $purchases;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Transaction\Transaction", mappedBy="user")
*/
protected $transactions;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Donation\CashDonation", mappedBy="user")
*/
protected $donations;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Email\Email", mappedBy="user", fetch="EXTRA_LAZY")
*/
protected $emails;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Auction\Bid", mappedBy="user")
*/
protected $bids;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Auction\BidNumber", mappedBy="user")
*/
protected $bidNumbers;
/**
* @ORM\Column(name="user_allow_admin_update", type="boolean")
*/
protected $allowAdminUpdate = true;
/**
* @ORM\ManyToOne(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Terms\UserTerms")
*/
protected $userTerms;
/**
* @ORM\Column(name="service_fee_type", type="text", length=20);
*/
protected $feeType = Campaign::FEE_USER;
/**
* @ORM\Column(name="notitication_preference", type="string", length=5, options={"fixed" = true});
*/
protected $notificationPreference = self::NOTIFICATION_SMS;
/**
* @ORM\ManyToOne(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\PaymentGateway\PaymentGateway")
*/
protected $preferredPaymentGateway;
/**
* @ORM\Column(name="is_test", type="boolean")
*/
protected $test = false;
/**
* @ORM\Column(name="email_optout", type="boolean")
*/
protected $emailOptout = false;
/**
* @ORM\ManyToOne(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Organization")
* @ORM\JoinColumn(name="last_visit_organization_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected ?Organization $lastVisitOrganization = null;
/**
* @ORM\ManyToOne(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Campaign")
* @ORM\JoinColumn(name="last_visit_campaign_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected ?Campaign $lastVisitCampaign = null;
/**
* @ORM\Column(type="datetime")
*/
protected $createdAt;
/**
* @ORM\Column(name="modals", type="simple_array", nullable=true)
*/
protected $modals = [];
// Not mapped, a hack around the registration form
protected $acceptTerms;
/**
* @ORM\Column(name="profile_update_dismissed_at", type="datetime", nullable=true)
*/
protected $profileUpdateDismissedAt;
/**
* @ORM\Column(name="has_logged_in", type="boolean")
* @Serialize\Expose
*/
protected $loggedIn = false;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Contact\Tag", mappedBy="user")
*/
protected $tags;
/**
* @ORM\Column(name="facebook_id", type="string", length=32, nullable=true)
*/
protected $facebookId;
/**
* @ORM\Column(name="facebook_access_token", type="string", length=64, nullable=true)
*/
protected $facebookAccessToken;
/**
* @ORM\Column(name="google_id", type="string", length=32, nullable=true)
*/
protected $googleId;
/**
* @ORM\Column(name="nvidia_id", type="string", length=32, nullable=true)
*/
protected $nvidiaId;
/**
* @ORM\Column(name="chg_id", type="string", length=255, nullable=true)
*/
protected $chgId;
/**
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Contact\Contact", mappedBy="user")
*/
protected $contacts;
/**
* @var CompanyMember[]|ArrayCollection
* @ORM\OneToMany(targetEntity="Bidcoz\Bundle\CoreBundle\Entity\Contact\CompanyMember", mappedBy="user")
*/
protected $companyMembers;
/**
* @ORM\Column(name="use_fast_list", type="boolean")
*/
protected $useFastList = false;
public function __construct()
{
parent::__construct();
$this->watchList = new ArrayCollection();
$this->tickets = new ArrayCollection();
$this->ticketGroups = new ArrayCollection();
$this->purchases = new ArrayCollection();
$this->transactions = new ArrayCollection();
$this->donations = new ArrayCollection();
$this->bids = new ArrayCollection();
$this->bidNumbers = new ArrayCollection();
$this->orgAdmins = new ArrayCollection();
$this->tags = new ArrayCollection();
$this->createdAt = new \DateTime();
$this->companyMembers = new ArrayCollection();
}
public function setId($id)
{
$this->id = $id;
return $this;
}
public function getWatchList()
{
return $this->watchList;
}
public function addWatchListItem(WatchListItem $item)
{
if (!$this->watchList->contains($item)) {
$this->watchList->add($item);
}
}
public function removeWatchListItem(WatchListItem $item)
{
if ($this->watchList->contains($item)) {
$this->watchList->removeElement($item);
}
}
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
public function getFirstName()
{
return $this->firstName;
}
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
public function getLastName()
{
return $this->lastName;
}
/**
* @Serialize\VirtualProperty
* @Serialize\SerializedName("name")
* @Serialize\Groups({"Default", "API"})
*/
public function getName()
{
$name = $this->firstName;
if ($this->lastName) {
$name .= ' '.$this->lastName;
}
return $name;
}
public function hasName(): bool
{
return (bool) $this->firstName && $this->lastName;
}
public function setAddress(Address $address)
{
$this->address = $address;
}
public function getAddress()
{
return $this->address;
}
public function setPhone($phone)
{
$this->phone = TextManipulator::normalizePhoneNumber($phone);
}
public function isPhoneValidForSMS(): bool
{
// We are going international! Phone number must start with a '+' (intl code)
return strlen($this->phone) > 0 && '+' === $this->phone[0];
}
public function hasValidPhoneForSmsOrHasOptedOut(): bool
{
return !$this->getSMSOptIn() || $this->isPhoneValidForSMS();
}
public function hasValidPhoneForSmsAndHasNotOptedOut(): bool
{
return $this->getSMSOptIn() && $this->isPhoneValidForSMS();
}
public function getPhone()
{
return $this->phone;
}
public function getSkipMobile(): bool
{
return $this->skipMobile;
}
public function setSkipMobile($value)
{
$this->skipMobile = (bool) $value;
if ($value) {
$this->notificationPreference = self::NOTIFICATION_EMAIL;
} else {
$this->notificationPreference = self::NOTIFICATION_SMS;
}
}
public function getSMSOptIn(): bool
{
return $this->smsOptIn;
}
public function setSMSOptIn($value)
{
$this->smsOptIn = (bool) $value;
if ($value) {
$this->notificationPreference = self::NOTIFICATION_SMS;
} else {
$this->notificationPreference = self::NOTIFICATION_EMAIL;
}
}
public function setTimezone($timezone)
{
$this->timezone = $timezone ?: self::DEFAULT_TIMEZONE;
}
public function getTimezone()
{
return $this->timezone;
}
public function getTickets()
{
return $this->tickets;
}
public function getCreditCards()
{
return $this->creditCards;
}
public function getTags()
{
return $this->tags;
}
public function getOrgAdmins()
{
return $this->orgAdmins;
}
public function getPurchases()
{
return $this->purchases;
}
public function setAllowAdminUpdate($allowAdminUpdate)
{
$this->allowAdminUpdate = $allowAdminUpdate;
}
public function getAllowAdminUpdate()
{
return $this->allowAdminUpdate;
}
public function setUserTerms(UserTerms $userTerms)
{
$this->userTerms = $userTerms;
}
public function getUserTerms()
{
return $this->userTerms;
}
public function setFeeType(string $feeType)
{
if (!array_key_exists($feeType, self::getFeeChoices())) {
return;
}
$this->feeType = $feeType;
}
public function getFeeType(): string
{
return $this->feeType ?: Campaign::FEE_USER;
}
public static function getFeeChoices()
{
return [
Campaign::FEE_USER => 'Accept',
Campaign::FEE_ORGANIZATION => 'Decline',
];
}
public function setNotificationPreference($notificationPreference)
{
$this->notificationPreference = $notificationPreference;
}
public function getNotificationPreference()
{
return $this->notificationPreference;
}
public function sendSMSNotifications()
{
return
$this->notificationPreference
&& self::NOTIFICATION_SMS === $this->notificationPreference
&& $this->isPhoneValidForSMS();
}
public static function getNotificationChoices()
{
return [
'Email' => self::NOTIFICATION_EMAIL,
'Text' => self::NOTIFICATION_SMS,
];
}
public function setPreferredPaymentGateway(PaymentGateway $preferredPaymentGateway)
{
$this->preferredPaymentGateway = $preferredPaymentGateway;
}
public function getPreferredPaymentGateway()
{
return $this->preferredPaymentGateway;
}
public function setTest($test)
{
$this->test = $test;
}
public function isTest()
{
return $this->test;
}
public function setEmailOptout($emailOptout)
{
$this->emailOptout = $emailOptout;
}
public function setEmail($email)
{
$email = Canonicalizer::canonicalize($email);
$this->email = $email;
$this->setEmailCanonical($email);
$this->setUsername($email);
$this->setUsernameCanonical($email);
}
public function isEmailOptout()
{
return $this->emailOptout;
}
public function setLastVisitOrganization(?Organization $lastVisitOrganization): void
{
$this->lastVisitOrganization = $lastVisitOrganization;
}
public function getLastVisitOrganization(): ?Organization
{
return $this->lastVisitOrganization;
}
public function setLastVisitCampaign(?Campaign $campaign): void
{
$this->lastVisitCampaign = $campaign;
$this->lastVisitOrganization = $campaign ? $campaign->getOrganization() : null;
}
public function getLastVisitCampaign(): ?Campaign
{
return $this->lastVisitCampaign;
}
public function setCreatedAt(\DateTime $date)
{
$this->createdAt = $date;
}
public function getCreatedAt()
{
return $this->createdAt;
}
public function setAcceptTerms($acceptTerms)
{
$this->acceptTerms = $acceptTerms;
}
/**
* @Assert\IsTrue(groups={"Registration"}, message="You must accept the User Terms of Use")
*/
public function getAcceptTerms()
{
return $this->acceptTerms;
}
public function getModals()
{
return $this->modals ?: [];
}
public function hasViewedModal($modal)
{
return in_array($modal, $this->modals);
}
public function viewModal($modal)
{
if (!$this->hasViewedModal($modal)) {
$this->modals[] = $modal;
}
}
public function removeModal($modal)
{
$idx = array_search($modal, $this->modals);
if (false !== $idx) {
unset($this->modals[$idx]);
}
}
public function dismissProfileUpdate()
{
$this->profileUpdateDismissedAt = new \DateTime();
}
public function showProfileUpdate()
{
if (!$this->profileUpdateDismissedAt) {
return true;
}
$then = new \DateTime('-8 hours');
return $this->profileUpdateDismissedAt < $then;
}
public function hasLoggedIn()
{
return $this->loggedIn;
}
public function setLoggedIn()
{
$this->loggedIn = true;
}
public function resetLoggedIn()
{
$this->loggedIn = false;
}
public function setFacebookId(int $facebookId)
{
$this->setFacebookId = $facebookId;
}
public function setFacebookAccessToken(string $accessToken)
{
$this->facebookAccessToken = $accessToken;
}
public function getGoogleId()
{
return $this->googleId;
}
public function setGoogleId(string $googleId)
{
$this->googleId = $googleId;
}
public function getNvidiaId()
{
return $this->nvidiaId;
}
public function setNvidiaId(string $nvidiaId)
{
$this->nvidiaId = $nvidiaId;
}
public function setChgId(string $chgId)
{
$this->chgId = $chgId;
}
public function getChgId()
{
return $this->chgId;
}
public function getCompanyMembers()
{
return $this->companyMembers;
}
public function getEmail()
{
return $this->email;
}
public function getUseFastList(): bool
{
return $this->useFastList;
}
}