src/Model/User.php line 53

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Harmonizely\Model;
  4. use DateTimeImmutable;
  5. use DateTimeZone;
  6. use Doctrine\Common\Collections\ArrayCollection;
  7. use Doctrine\Common\Collections\Collection;
  8. use Doctrine\Common\Collections\Criteria;
  9. use Exception;
  10. use FOS\UserBundle\Model\User as BaseUser;
  11. use Harmonizely\Core\DTO\SecondFactorCredentialsDTO;
  12. use Harmonizely\Core\StringUtil;
  13. use Harmonizely\DTO\SuperAdmin\Customer\Response\CustomerDetailedDTO;
  14. use Harmonizely\DTO\User\Response\UserDTO;
  15. use Harmonizely\Entity\ApiKeyEntity;
  16. use Harmonizely\Entity\Contract\INamedObjectEntity;
  17. use Harmonizely\Entity\MigrationSubscriptionEntity;
  18. use Harmonizely\Entity\OrganizationTagEntity;
  19. use Harmonizely\Entity\ReviewEntity;
  20. use Harmonizely\Entity\RoutingFormEntity;
  21. use Harmonizely\Entity\UserCancellationPolicyEntity;
  22. use Harmonizely\Entity\UserEmailLogEntity;
  23. use Harmonizely\Entity\UserEmailUnsubscribeEntity;
  24. use Harmonizely\Entity\UserGoogleAuthenticatorEntity;
  25. use Harmonizely\Entity\UserLimitEntity;
  26. use Harmonizely\Entity\UserLoginCodeEntity;
  27. use Harmonizely\Entity\UserOAuthEntity;
  28. use Harmonizely\Entity\UserPushNotificationLogEntity;
  29. use Harmonizely\Entity\UserRelationEntity;
  30. use Harmonizely\Entity\UserSmsLogEntity;
  31. use Harmonizely\Entity\UserSsoEntity;
  32. use Harmonizely\Entity\UserWidgetEntity;
  33. use Harmonizely\Entity\ZapierEntity;
  34. use Harmonizely\Service\Subscription\Voter\SubscriptionVoter;
  35. use Harmonizely\Types\CalendarLayoutType;
  36. use Harmonizely\Types\UserSsoLoginType;
  37. use libphonenumber\PhoneNumber;
  38. use libphonenumber\PhoneNumberFormat;
  39. use libphonenumber\PhoneNumberUtil;
  40. use Symfony\Component\HttpFoundation\File\File;
  41. use Symfony\Component\Validator\Constraints as Assert;
  42. use Harmonizely\Entity\UserSocialLinkEntity;
  43. use Harmonizely\Entity\UserTaxEntity;
  44. use Symfony\Component\Security\Core\User\EquatableInterface;
  45. use Symfony\Component\Security\Core\User\UserInterface as BaseUserInterface;
  46. use Harmonizely\Types\DateFormatType;
  47. use Harmonizely\Entity\PollEntity;
  48. use Harmonizely\DTO\User\Response\SimpleUserDTO;
  49. class User extends BaseUser implements EquatableInterfaceUserInterfaceINamedObjectEntityBannerInterface
  50. {
  51.     use RtlTrait;
  52.     use BannerTrait;
  53.     use AdaTrait;
  54.     use TimestampableTrait;
  55.     use UuidTrait {
  56.         __construct as private initUuid;
  57.     }
  58.     /**
  59.      * @var mixed
  60.      */
  61.     protected $id;
  62.     /**
  63.      * @var string
  64.      */
  65.     protected $firstName;
  66.     /**
  67.      * @var string
  68.      */
  69.     protected $lastName;
  70.     /**
  71.      * @var string
  72.      */
  73.     protected $fullName '';
  74.     /**
  75.      * @var CalendarAccountInterface
  76.      */
  77.     protected $calendarAccount;
  78.     /**
  79.      * @var CalendarAccountInterface[]|Collection
  80.      */
  81.     protected $calendarAccounts;
  82.     /**
  83.      * @Assert\NotBlank
  84.      *
  85.      * @var string
  86.      */
  87.     protected $slug;
  88.     /**
  89.      * @var string|null
  90.      */
  91.     protected $intro;
  92.     /**
  93.      * @var string
  94.      */
  95.     protected $timezone;
  96.     /**
  97.      * @var string
  98.      */
  99.     protected $locale;
  100.     /**
  101.      * @var File
  102.      */
  103.     protected $avatarFile;
  104.     /**
  105.      * @var string
  106.      */
  107.     protected $avatarName;
  108.     /**
  109.      * @var int
  110.      */
  111.     protected $avatarSize;
  112.     /**
  113.      * @var int|null
  114.      */
  115.     protected $companyLogoFile;
  116.     /**
  117.      * @var int|null
  118.      */
  119.     protected $companyLogoName;
  120.     /**
  121.      * @var int|null
  122.      */
  123.     protected $companyLogoSize;
  124.     /**
  125.      * @var SubscriptionInterface
  126.      */
  127.     protected $subscription;
  128.     /**
  129.      * @var Collection
  130.      */
  131.     protected $integrations;
  132.     /**
  133.      * @var bool
  134.      */
  135.     protected $brandingEnabled true;
  136.     /**
  137.      * @var bool
  138.      */
  139.     protected $isProxyEnabled false;
  140.     /**
  141.      * @var SchedulingPageAppearance
  142.      */
  143.     protected $schedulingPageAppearance;
  144.     /**
  145.      * @var string
  146.      */
  147.     private $domain;
  148.     /**
  149.      * @var Collection|Member[]
  150.      */
  151.     private $members;
  152.     /**
  153.      * @var Collection|Event[]
  154.      */
  155.     private $events;
  156.     /**
  157.      * @var Collection|UserSmsLogEntity[]
  158.      */
  159.     private $userSmsLog;
  160.     /**
  161.      * @var Collection|UserEmailLogEntity[]
  162.      */
  163.     private $userEmailLog;
  164.     /**
  165.      * @var Collection|UserPushNotificationLogEntity[]
  166.      */
  167.     private $userPushNotificationLog;
  168.     /**
  169.      * @var Collection|UserLimitEntity[]
  170.      */
  171.     private $userLimit;
  172.     /**
  173.      * @var Collection|UserTaxEntity[]
  174.      */
  175.     private $tax;
  176.     /**
  177.      * @var Collection|PollEntity[]
  178.      */
  179.     private $polls;
  180.     /**
  181.      * @var Collection|RoutingFormEntity[]
  182.      * */
  183.     private $routingForms;
  184.     /**
  185.      * @var Collection|ZapierEntity[]
  186.      */
  187.     private $zapiers;
  188.     /**
  189.      * @var Collection|ApiKeyEntity[]
  190.      */
  191.     private $apiKeys;
  192.     /**
  193.      * @var Collection|UserLoginCodeEntity[]
  194.      */
  195.     private $userLoginCode;
  196.     /**
  197.      * @var array|ArrayCollection
  198.      */
  199.     protected $socialLinks = [];
  200.     /**
  201.      * @var string|null
  202.      */
  203.     private $sender;
  204.     /**
  205.      * @var ApiKey
  206.      */
  207.     protected $apiKey;
  208.     protected ?string $timeFormat UserInterface::TWELVE_HOURS_TIME_FORMAT;
  209.     protected ?string $dateFormat DateFormatType::TYPE_DD_MM_YYYY;
  210.     protected ?string $clientTimeFormat UserInterface::AUTO_TIME_FORMAT;
  211.     private ?int $dayliteId;
  212.     private ?UserPreferences $preferences;
  213.     private ?PhoneNumber $phoneNumber;
  214.     protected ?int $consent UserInterface::CONSENT_ACCEPTED;
  215.     /**
  216.      * @var string|null
  217.      */
  218.     private ?string $referral;
  219.     /**
  220.      * @var string
  221.      */
  222.     private string $calendarLayout CalendarLayoutType::TYPE_WEEKLY;
  223.     /**
  224.      * @var bool
  225.      */
  226.     protected bool $hideUnavailableDates false;
  227.     /**
  228.      * @var bool
  229.      */
  230.     protected bool $sundayIsFirstDay false;
  231.     /**
  232.      * @var bool
  233.      */
  234.     protected bool $requireSetPassword false;
  235.     /**
  236.      * @var bool
  237.      */
  238.     protected bool $requireConfirmEmail false;
  239.     /**
  240.      * @var UserGoogleAuthenticatorEntity|null
  241.      */
  242.     private ?UserGoogleAuthenticatorEntity $googleAuthenticator null;
  243.     /**
  244.      * @var UserSocialLinkEntity|null $socialLink
  245.      */
  246.     private ?UserSocialLinkEntity $socialLink null;
  247.     /**
  248.      * @var UserSsoEntity|null
  249.      */
  250.     private ?UserSsoEntity $userSso null;
  251.     private ?UserCancellationPolicyEntity $userCancellationPolicy null;
  252.     private ?UserWidgetEntity $userWidget null;
  253.     /**
  254.      * @var Collection|null
  255.      */
  256.     private ?Collection $userToken null;
  257.     /**
  258.      * @var Collection|null
  259.      */
  260.     private ?Collection $userDeviceToken null;
  261.     /**
  262.      * @var Collection|null
  263.      */
  264.     private ?Collection $userApiStatistic null;
  265.     /**
  266.      * @var Collection|null
  267.      */
  268.     private ?Collection $userExport null;
  269.     /**
  270.      * @var Collection|UserOAuthEntity[]
  271.      */
  272.     private Collection $userOAuth;
  273.     /**
  274.      * @var Collection
  275.      */
  276.     protected Collection $userNews;
  277.     /**
  278.      * @var Collection
  279.      */
  280.     protected Collection $organizationTags;
  281.     /**
  282.      * @var Collection
  283.      */
  284.     protected Collection $userCategories;
  285.     /**
  286.      * @var MigrationSubscriptionEntity|null
  287.      */
  288.     protected ?MigrationSubscriptionEntity $migrationSubscription;
  289.     /**
  290.      * @var UserEmailUnsubscribeEntity |null
  291.      */
  292.     protected ?UserEmailUnsubscribeEntity $userEmailUnsubscribe;
  293.     /**
  294.      * @var ReviewEntity|null
  295.      */
  296.     protected ?ReviewEntity $review;
  297.     /**
  298.      * @var string|null
  299.      */
  300.     protected ?string $address '';
  301.     /**
  302.      * @var string|null
  303.      */
  304.     protected ?string $state '';
  305.     /**
  306.      * @var string|null
  307.      */
  308.     protected ?string $city '';
  309.     /**
  310.      * @var string|null
  311.      */
  312.     protected ?string $zip '';
  313.     /**
  314.      * @var string|null
  315.      */
  316.     protected ?string $countryId '';
  317.     /**
  318.      * @var float|null
  319.      */
  320.     protected ?float $lat null;
  321.     /**
  322.      * @var float|null
  323.      */
  324.     protected ?float $lng null;
  325.     /**
  326.      * @var int|null
  327.      */
  328.     protected ?int $verificationCode null;
  329.     /**
  330.      * @var string|null
  331.      */
  332.     protected ?string $otherCategory '';
  333.     /**
  334.      * @var bool
  335.      */
  336.     protected ?bool $showAddressInEmail true;
  337.     /**
  338.      * @var string|null
  339.      */
  340.     protected ?string $lastTwoFactorCode '';
  341.     /**
  342.      * @var bool
  343.      */
  344.     private bool $ssoLoginAllowed;
  345.     /**
  346.      * User subscriptions
  347.      *
  348.      * @var Collection
  349.      */
  350.     protected Collection $subscriptions;
  351.     /**
  352.      * @var Collection
  353.      */
  354.     protected Collection $userEventTypeTag;
  355.     /**
  356.      * @var Collection|UserRelationEntity[]
  357.      */
  358.     protected Collection $relatedUsers;
  359.     /**
  360.      * @var string|null
  361.      */
  362.     private ?string $welcomeTourStep;
  363.     /**
  364.      * @var bool
  365.      */
  366.     private bool $secondFactorSkipped false;
  367.     /**
  368.      * @var bool
  369.      */
  370.     private bool $tutorialSkipped false;
  371.     /**
  372.      * User constructor.
  373.      */
  374.     public function __construct()
  375.     {
  376.         $this->setCreatedAt(new DateTime());
  377.         $this->integrations = new ArrayCollection();
  378.         $this->members = new ArrayCollection();
  379.         $this->calendarAccounts = new ArrayCollection();
  380.         $this->organizationTags = new ArrayCollection();
  381.         $this->userCategories = new ArrayCollection();
  382.         $this->userOAuth = new ArrayCollection();
  383.         $this->userNews = new ArrayCollection();
  384.         $this->subscriptions = new ArrayCollection();
  385.         $this->socialLink = new UserSocialLinkEntity();
  386.         $this->relatedUsers = new ArrayCollection();
  387.         $this->initUuid();
  388.         $this->generateVerificationCode();
  389.         parent::__construct();
  390.     }
  391.     /**
  392.      * {@inheritdoc}
  393.      */
  394.     public function setLastLogin(\DateTime $time null)
  395.     {
  396.         if (!$this->lastLogin || $time->diff($this->lastLogin)->days 0) {
  397.             if (mt_rand(110) == 1) {
  398.                 $this->lastLogin $time;
  399.             }
  400.         }
  401.         return $this;
  402.     }
  403.     public function getDirectoryCompanyLogin(): string
  404.     {
  405.         return 'simplymeet_' $this->getId();
  406.     }
  407.     /**
  408.      * @return void
  409.      */
  410.     public function useVerificationCode(): void
  411.     {
  412.         $this->verificationCode null;
  413.     }
  414.     public function generateVerificationCode(): void
  415.     {
  416.         $this->verificationCode StringUtil::getSecretCode();
  417.     }
  418.     /**
  419.      * @return int|null
  420.      */
  421.     public function getVerificationCode(): ?int
  422.     {
  423.         return $this->verificationCode;
  424.     }
  425.     public function setEmail($email)
  426.     {
  427.         $email $email ?? '';
  428.         parent::setEmail($email);
  429.         $this->setUsername($email);
  430.     }
  431.     /**
  432.      * {@inheritdoc}
  433.      */
  434.     public function getFirstName(): string
  435.     {
  436.         $parts explode(' '$this->fullName);
  437.         return array_shift($parts);
  438.     }
  439.     /**
  440.      * {@inheritdoc}
  441.      */
  442.     public function setFirstName(string $firstName)
  443.     {
  444.         $this->firstName $firstName;
  445.     }
  446.     /**
  447.      * {@inheritdoc}
  448.      */
  449.     public function getLastName(): string
  450.     {
  451.         return $this->lastName;
  452.     }
  453.     /**
  454.      * {@inheritdoc}
  455.      */
  456.     public function setLastName(string $lastName)
  457.     {
  458.         $this->lastName $lastName;
  459.     }
  460.     /**
  461.      * @return CalendarAccountInterface[]|Collection
  462.      */
  463.     public function getCalendarAccounts(): Collection
  464.     {
  465.         return $this->calendarAccounts;
  466.     }
  467.     /**
  468.      * @param int $id
  469.      * @return CalendarAccountInterface|null
  470.      */
  471.     public function getCalendarAccountById(int $id): ?CalendarAccountInterface
  472.     {
  473.         $calendarAccount $this->calendarAccounts->filter(function (CalendarAccountInterface $calendarAccount) use ($id) {
  474.             return $calendarAccount->getId() === $id;
  475.         })->first();
  476.         return $calendarAccount ?: null;
  477.     }
  478.     /**
  479.      * @return CalendarAccountInterface[]|Collection
  480.      */
  481.     public function getWritableCalendarAccounts(): Collection
  482.     {
  483.         return $this->calendarAccounts->filter(function (CalendarAccountInterface $calendarAccount) {
  484.             return $calendarAccount->isWritable();
  485.         });
  486.     }
  487.     public function setCalendarAccounts(Collection $calendarAccounts): void
  488.     {
  489.         $this->calendarAccounts $calendarAccounts;
  490.     }
  491.     public function addCalendarAccount(CalendarAccountInterface $calendarAccount): void
  492.     {
  493.         if (!$this->hasCalendarAccount($calendarAccount)) {
  494.             $this->calendarAccounts->add($calendarAccount);
  495.             $calendarAccount->setUser($this);
  496.         }
  497.     }
  498.     public function removeCalendarAccount(CalendarAccountInterface $calendarAccount): void
  499.     {
  500.         if ($this->hasCalendarAccount($calendarAccount)) {
  501.             $this->calendarAccounts->removeElement($calendarAccount);
  502.             $calendarAccount->setUser(null);
  503.         }
  504.     }
  505.     public function hasCalendarAccount(CalendarAccountInterface $calendarAccount): bool
  506.     {
  507.         return $this->calendarAccounts->contains($calendarAccount);
  508.     }
  509.     public function hasCalendarConnected(string $type): bool
  510.     {
  511.         foreach ($this->calendarAccounts as $calendarAccount) {
  512.             $calendarService $calendarAccount->getCalendarService();
  513.             if ($calendarService->getType() === $type) {
  514.                 return true;
  515.             }
  516.         }
  517.         return false;
  518.     }
  519.     /**
  520.      * {@inheritdoc}
  521.      */
  522.     public function getSlug(): ?string
  523.     {
  524.         return $this->slug;
  525.     }
  526.     /**
  527.      * {@inheritdoc}
  528.      */
  529.     public function setSlug(?string $slug): void
  530.     {
  531.         $this->slug $slug;
  532.     }
  533.     /**
  534.      * {@inheritdoc}
  535.      */
  536.     public function getFullName(): string
  537.     {
  538.         return $this->fullName;
  539.     }
  540.     /**
  541.      * {@inheritdoc}
  542.      */
  543.     public function setFullName(string $fullName): void
  544.     {
  545.         $this->fullName $fullName;
  546.     }
  547.     /**
  548.      * {@inheritdoc}
  549.      */
  550.     public function getIntro(): ?string
  551.     {
  552.         return $this->intro;
  553.     }
  554.     /**
  555.      * {@inheritdoc}
  556.      */
  557.     public function setIntro(?string $intro): void
  558.     {
  559.         $this->intro $intro;
  560.     }
  561.     /**
  562.      * {@inheritdoc}
  563.      */
  564.     public function getTimezone(): ?string
  565.     {
  566.         return $this->timezone;
  567.     }
  568.     /**
  569.      * {@inheritdoc}
  570.      */
  571.     public function setTimezone(?string $timezone): void
  572.     {
  573.         $this->timezone $timezone;
  574.     }
  575.     /**
  576.      * {@inheritdoc}
  577.      */
  578.     public function getLocale(): ?string
  579.     {
  580.         return $this->locale;
  581.     }
  582.     /**
  583.      * {@inheritdoc}
  584.      */
  585.     public function setLocale(?string $locale): void
  586.     {
  587.         $this->locale $locale;
  588.     }
  589.     /**
  590.      * @return bool
  591.      */
  592.     public function isAutoLocale(): bool
  593.     {
  594.         return $this->getLocale() === 'auto';
  595.     }
  596.     /**
  597.      * @return File
  598.      */
  599.     public function getAvatarFile(): ?File
  600.     {
  601.         return $this->avatarFile;
  602.     }
  603.     /**
  604.      * @param File $avatarFile
  605.      *
  606.      * @throws Exception
  607.      */
  608.     public function setAvatarFile(?File $avatarFile): void
  609.     {
  610.         $this->avatarFile $avatarFile;
  611.         if (null !== $avatarFile) {
  612.             $this->updatedAt = new DateTimeImmutable();
  613.         }
  614.     }
  615.     /**
  616.      * @return string
  617.      */
  618.     public function getAvatarName(): ?string
  619.     {
  620.         return $this->avatarName;
  621.     }
  622.     /**
  623.      * @param string $avatarName
  624.      */
  625.     public function setAvatarName(?string $avatarName): void
  626.     {
  627.         $this->avatarName $avatarName;
  628.     }
  629.     /**
  630.      * @return int
  631.      */
  632.     public function getAvatarSize(): ?int
  633.     {
  634.         return $this->avatarSize;
  635.     }
  636.     /**
  637.      * @param int $avatarSize
  638.      */
  639.     public function setAvatarSize(?int $avatarSize): void
  640.     {
  641.         $this->avatarSize $avatarSize;
  642.     }
  643.     public function getSubscription(): ?SubscriptionInterface
  644.     {
  645.         return $this->subscription;
  646.     }
  647.     public function setSubscription(?SubscriptionInterface $subscription): void
  648.     {
  649.         $this->subscription $subscription;
  650.     }
  651.     public function getIntegrations(): Collection
  652.     {
  653.         return $this->integrations;
  654.     }
  655.     public function setIntegrations(Collection $integrations): void
  656.     {
  657.         $this->integrations $integrations;
  658.     }
  659.     /**
  660.      * @param string $type
  661.      * @return false|IntegrationInterface
  662.      */
  663.     public function getIntegrationByType(string $type)
  664.     {
  665.         $criteria Criteria::create()->where(Criteria::expr()->eq('type'$type));
  666.         return $this->integrations->matching($criteria)->first();
  667.     }
  668.     public function addIntegration(IntegrationInterface $integration): void
  669.     {
  670.         if (!$this->hasIntegration($integration)) {
  671.             $this->integrations->add($integration);
  672.             $integration->setUser($this);
  673.         }
  674.     }
  675.     public function removeIntegration(IntegrationInterface $integration): void
  676.     {
  677.         if ($this->hasIntegration($integration)) {
  678.             $this->integrations->removeElement($integration);
  679.             $integration->setUser(null);
  680.         }
  681.     }
  682.     public function hasIntegration(IntegrationInterface $integration): bool
  683.     {
  684.         return $this->integrations->contains($integration);
  685.     }
  686.     public function isBrandingEnabled(): bool
  687.     {
  688.         if (!SubscriptionVoter::staticVoteOnAttribute(SubscriptionVoter::WHITE_LABEL$this)) {
  689.             return true;
  690.         }
  691.         return $this->brandingEnabled;
  692.     }
  693.     public function isCustomCssAvailable(): bool
  694.     {
  695.         return SubscriptionVoter::staticVoteOnAttribute(SubscriptionVoter::WHITE_LABEL$this);
  696.     }
  697.     public function setBrandingEnabled(bool $brandingEnabled): void
  698.     {
  699.         $this->brandingEnabled $brandingEnabled;
  700.     }
  701.     public function isProxyEnabled(): bool
  702.     {
  703.         return $this->isProxyEnabled;
  704.     }
  705.     public function setIsProxyEnabled(bool $isProxyEnabled): void
  706.     {
  707.         $this->isProxyEnabled $isProxyEnabled;
  708.     }
  709.     public function getDefaultOrganization(): ?Organization
  710.     {
  711.         if ($this->members->count() > 0) {
  712.             return $this->members->first()->getOrganization();
  713.         }
  714.         return null;
  715.     }
  716.     public function getSchedulingPageAppearance(): SchedulingPageAppearance
  717.     {
  718.         if (false === $this->schedulingPageAppearance instanceof SchedulingPageAppearance) {
  719.             $this->schedulingPageAppearance = new UserSchedulingPageAppearance();
  720.             $this->schedulingPageAppearance->setUser($this);
  721.         }
  722.         if (!$this->schedulingPageAppearance->getConfig()) {
  723.             $this->schedulingPageAppearance->setConfig(SchedulingPageAppearance::DEFAULT_CONFIG);
  724.         }
  725.         return $this->schedulingPageAppearance;
  726.     }
  727.     public function setSchedulingPageAppearance(?SchedulingPageAppearance $schedulingPageAppearance): void
  728.     {
  729.         $this->schedulingPageAppearance $schedulingPageAppearance;
  730.     }
  731.     public function getDomain(): ?string
  732.     {
  733.         return $this->domain;
  734.     }
  735.     public function getUserOrOrganizationDomain(): ?string
  736.     {
  737.         $domain null;
  738.         if ($this->domain) {
  739.             $domain $this->domain;
  740.         } else {
  741.             $organization $this->getDefaultOrganization();
  742.             if ($organization && $organization->getDomain()) {
  743.                 $domain $organization->getDomain();
  744.             }
  745.         }
  746.         return $domain;
  747.     }
  748.     public function setDomain(?string $domain): void
  749.     {
  750.         $this->domain $domain;
  751.     }
  752.     public function getMembers(): Collection
  753.     {
  754.         return $this->members;
  755.     }
  756.     public function setMembers(Collection $members): void
  757.     {
  758.         $this->members $members;
  759.     }
  760.     public function belongsToOrganization(Organization $organization)
  761.     {
  762.         $members $organization->getMembers();
  763.         $user $members->filter(function (Member $member) {
  764.             return $member->getUser()->getId() === $this->getId();
  765.         });
  766.         return false === $user->isEmpty();
  767.     }
  768.     public function getSender(): ?string
  769.     {
  770.         return $this->sender;
  771.     }
  772.     public function setSender(?string $sender): void
  773.     {
  774.         $this->sender $sender;
  775.     }
  776.     public function getCompanyLogoFile(): ?File
  777.     {
  778.         return $this->companyLogoFile;
  779.     }
  780.     public function setCompanyLogoFile(?File $companyLogoFile): void
  781.     {
  782.         $this->companyLogoFile $companyLogoFile;
  783.         if (null !== $companyLogoFile) {
  784.             $this->updatedAt = new DateTimeImmutable();
  785.         }
  786.     }
  787.     public function getCompanyLogoName(): ?string
  788.     {
  789.         return $this->companyLogoName;
  790.     }
  791.     public function setCompanyLogoName(?string $companyLogoName): void
  792.     {
  793.         $this->companyLogoName $companyLogoName;
  794.     }
  795.     public function getCompanyLogoSize(): ?int
  796.     {
  797.         return $this->companyLogoSize;
  798.     }
  799.     public function setCompanyLogoSize(?int $companyLogoSize): void
  800.     {
  801.         $this->companyLogoSize $companyLogoSize;
  802.     }
  803.     public function getTimeFormat(): ?string
  804.     {
  805.         return $this->timeFormat;
  806.     }
  807.     public function setTimeFormat(?string $timeFormat): void
  808.     {
  809.         $this->timeFormat $timeFormat;
  810.     }
  811.     public function getDateFormat(): ?string
  812.     {
  813.         return $this->dateFormat;
  814.     }
  815.     public function setDateFormat(?string $dateFormat): void
  816.     {
  817.         $this->dateFormat $dateFormat;
  818.     }
  819.     /**
  820.      * @deprecated
  821.      * @return string|null
  822.      */
  823.     public function getClientTimeFormat(): ?string
  824.     {
  825.         return $this->clientTimeFormat;
  826.     }
  827.     /**
  828.      * @deprecated 
  829.      * @param string|null $clientTimeFormat
  830.      * @return void
  831.      */
  832.     public function setClientTimeFormat(?string $clientTimeFormat): void
  833.     {
  834.         $this->clientTimeFormat $clientTimeFormat;
  835.     }
  836.     public function getDayliteId(): ?int
  837.     {
  838.         return $this->dayliteId;
  839.     }
  840.     public function setDayliteId(?int $dayliteId): void
  841.     {
  842.         $this->dayliteId $dayliteId;
  843.     }
  844.     public function getPreferences(): UserPreferences
  845.     {
  846.         if (false === $this->preferences instanceof UserPreferences) {
  847.             $this->preferences = new UserPreferences();
  848.             $this->preferences->setUser($this);
  849.         }
  850.         return $this->preferences;
  851.     }
  852.     public function setPreferences(?UserPreferences $preferences): void
  853.     {
  854.         $this->preferences $preferences;
  855.     }
  856.     public function getPhoneNumber(): ?PhoneNumber
  857.     {
  858.         return $this->phoneNumber;
  859.     }
  860.     public function getInternationalPhoneNumber(): string
  861.     {
  862.         if (!$this->phoneNumber instanceof PhoneNumber) {
  863.             return '';
  864.         }
  865.         $phoneUtil PhoneNumberUtil::getInstance();
  866.         return $phoneUtil->format($this->phoneNumberPhoneNumberFormat::E164);
  867.     }
  868.     public function setPhoneNumber(?PhoneNumber $phoneNumber): void
  869.     {
  870.         $this->phoneNumber $phoneNumber;
  871.     }
  872.     public function getHelpScoutSignature(): string
  873.     {
  874.         return hash_hmac(
  875.             'sha256',
  876.             $this->emailCanonical,
  877.             'yHXRcpT4sgbtldHeLccCrlUBl1k5yPTKc8xiojCcQRU='
  878.         );
  879.     }
  880.     public function getConsent(): ?int
  881.     {
  882.         return $this->consent;
  883.     }
  884.     public function setConsent(?int $consent): void
  885.     {
  886.         $this->consent $consent;
  887.     }
  888.     /**
  889.      * @param string|null $referral
  890.      */
  891.     public function setReferral(?string $referral): void
  892.     {
  893.         $this->referral $referral;
  894.     }
  895.     /**
  896.      * @return string|null
  897.      */
  898.     public function getReferral(): ?string
  899.     {
  900.         return $this->referral;
  901.     }
  902.     /**
  903.      * Return 2fa authentication type
  904.      *
  905.      * @return string|null
  906.      */
  907.     public function getSecondAuthenticationType(): ?string
  908.     {
  909.         $types $this->getAllowedSecondAuthenticationTypes();
  910.         $type reset($types);
  911.         if ($type) {
  912.             return $type;
  913.         }
  914.         return null;
  915.     }
  916.     /**
  917.      * Return allowed 2fa types
  918.      *
  919.      * @return array
  920.      */
  921.     public function getAllowedSecondAuthenticationTypes(): array
  922.     {
  923.         $result = [];
  924.         if ($this->googleAuthenticator) {
  925.             $result[] = SecondFactorCredentialsDTO::TYPE_GA;
  926.         }
  927.         return $result;
  928.     }
  929.     /**
  930.      * Return Google Authenticator secret code
  931.      *
  932.      * @return string|null
  933.      */
  934.     public function getGASecretCode(): ?string
  935.     {
  936.         if ($this->googleAuthenticator) {
  937.             return $this->googleAuthenticator->getSecret();
  938.         }
  939.         return null;
  940.     }
  941.     /**
  942.      * Return Google Authenticator secret code
  943.      *
  944.      * @param string $secret
  945.      * @return void
  946.      */
  947.     public function setGASecretCode(string $secret): void
  948.     {
  949.         if ($this->googleAuthenticator) {
  950.             $this->googleAuthenticator->changeSecret($secret);
  951.         } else {
  952.             $this->googleAuthenticator = new UserGoogleAuthenticatorEntity($this$secret);
  953.         }
  954.     }
  955.     /**
  956.      * @param UserGoogleAuthenticatorEntity|null $googleAuthenticator
  957.      */
  958.     public function setGoogleAuthenticator(?UserGoogleAuthenticatorEntity $googleAuthenticator): void
  959.     {
  960.         $this->googleAuthenticator $googleAuthenticator;
  961.     }
  962.     /**
  963.      * @return UserGoogleAuthenticatorEntity|null
  964.      */
  965.     public function getGoogleAuthenticator(): ?UserGoogleAuthenticatorEntity
  966.     {
  967.         return $this->googleAuthenticator;
  968.     }
  969.     /**
  970.      * Clear GA code
  971.      */
  972.     public function deleteGoogleAuthenticator(): void
  973.     {
  974.         $this->googleAuthenticator null;
  975.     }
  976.     /**
  977.      * @param UserSsoEntity|null $userSso
  978.      */
  979.     public function setUserSso(?UserSsoEntity $userSso): void
  980.     {
  981.         $this->userSso $userSso;
  982.     }
  983.     /**
  984.      * @return UserSsoEntity|null
  985.      */
  986.     public function getUserSso(): ?UserSsoEntity
  987.     {
  988.         return $this->userSso;
  989.     }
  990.     /**
  991.      * @return Collection
  992.      */
  993.     public function getOrganizationTags(): Collection
  994.     {
  995.         return $this->organizationTags;
  996.     }
  997.     /**
  998.      * Add organization tag
  999.      *
  1000.      * @param OrganizationTagEntity $organizationTag
  1001.      */
  1002.     public function addOrganizationTag(OrganizationTagEntity $organizationTag): void
  1003.     {
  1004.         if (!$this->organizationTags->contains($organizationTag)) {
  1005.             $this->organizationTags->add($organizationTag);
  1006.         }
  1007.     }
  1008.     /**
  1009.      * @param OrganizationTagEntity $organizationTag
  1010.      * @return void
  1011.      */
  1012.     public function removeOrganizationTag(OrganizationTagEntity $organizationTag): void
  1013.     {
  1014.         if ($this->organizationTags->contains($organizationTag)) {
  1015.             $this->organizationTags->removeElement($organizationTag);
  1016.         }
  1017.     }
  1018.     /**
  1019.      * @return void
  1020.      */
  1021.     public function clearOrganizationTag(): void
  1022.     {
  1023.         $this->organizationTags = new ArrayCollection();
  1024.     }
  1025.     public function clearUserCategories(): void
  1026.     {
  1027.         $this->userCategories = new ArrayCollection();
  1028.     }
  1029.     /**
  1030.      * @return Collection
  1031.      */
  1032.     public function getUserCategories(): Collection
  1033.     {
  1034.         return $this->userCategories;
  1035.     }
  1036.     /**
  1037.      * @param Collection $userCategories
  1038.      */
  1039.     public function setUserCategories(Collection $userCategories): void
  1040.     {
  1041.         $this->userCategories $userCategories;
  1042.     }
  1043.     /**
  1044.      * @param string $calendarLayout
  1045.      */
  1046.     public function setCalendarLayout(string $calendarLayout): void
  1047.     {
  1048.         $this->calendarLayout $calendarLayout;
  1049.     }
  1050.     /**
  1051.      * @return string
  1052.      */
  1053.     public function getCalendarLayout(): string
  1054.     {
  1055.         return $this->calendarLayout;
  1056.     }
  1057.     /**
  1058.      * @param bool $hideUnavailableDates
  1059.      */
  1060.     public function setHideUnavailableDates(bool $hideUnavailableDates): void
  1061.     {
  1062.         $this->hideUnavailableDates $hideUnavailableDates;
  1063.     }
  1064.     /**
  1065.      * @return bool
  1066.      */
  1067.     public function isHideUnavailableDates(): bool
  1068.     {
  1069.         return $this->hideUnavailableDates;
  1070.     }
  1071.     /**
  1072.      * @param bool $sundayIsFirstDay
  1073.      */
  1074.     public function setSundayIsFirstDay(bool $sundayIsFirstDay): void
  1075.     {
  1076.         $this->sundayIsFirstDay $sundayIsFirstDay;
  1077.     }
  1078.     /**
  1079.      * @return bool
  1080.      */
  1081.     public function isSundayIsFirstDay(): bool
  1082.     {
  1083.         return $this->sundayIsFirstDay;
  1084.     }
  1085.     /**
  1086.      * @param bool $requireSetPassword
  1087.      */
  1088.     public function setRequireSetPassword(bool $requireSetPassword): void
  1089.     {
  1090.         $this->requireSetPassword $requireSetPassword;
  1091.     }
  1092.     /**
  1093.      * @return bool
  1094.      */
  1095.     public function isRequireSetPassword(): bool
  1096.     {
  1097.         return $this->requireSetPassword;
  1098.     }
  1099.     /**
  1100.      * @return bool
  1101.      */
  1102.     public function isRequireConfirmEmail(): bool
  1103.     {
  1104.         return $this->requireConfirmEmail;
  1105.     }
  1106.     /**
  1107.      * @param bool $requireConfirmEmail
  1108.      */
  1109.     public function setRequireConfirmEmail(bool $requireConfirmEmail): void
  1110.     {
  1111.         $this->requireConfirmEmail $requireConfirmEmail;
  1112.     }
  1113.     /**
  1114.      * @param string|null $address
  1115.      */
  1116.     public function setAddress(?string $address): void
  1117.     {
  1118.         $this->address $address;
  1119.     }
  1120.     /**
  1121.      * @return string|null
  1122.      */
  1123.     public function getAddress(): ?string
  1124.     {
  1125.         return $this->address;
  1126.     }
  1127.     /**
  1128.      * @return string|null
  1129.      */
  1130.     public function getState(): ?string
  1131.     {
  1132.         return $this->state;
  1133.     }
  1134.     /**
  1135.      * @param string|null $state
  1136.      */
  1137.     public function setState(?string $state): void
  1138.     {
  1139.         $this->state $state;
  1140.     }
  1141.     /**
  1142.      * @return string|null
  1143.      */
  1144.     public function getCity(): ?string
  1145.     {
  1146.         return $this->city;
  1147.     }
  1148.     /**
  1149.      * @param string|null $city
  1150.      */
  1151.     public function setCity(?string $city): void
  1152.     {
  1153.         $this->city $city;
  1154.     }
  1155.     /**
  1156.      * @return string|null
  1157.      */
  1158.     public function getZip(): ?string
  1159.     {
  1160.         return $this->zip;
  1161.     }
  1162.     /**
  1163.      * @param string|null $zip
  1164.      */
  1165.     public function setZip(?string $zip): void
  1166.     {
  1167.         $this->zip $zip;
  1168.     }
  1169.     /**
  1170.      * @return string|null
  1171.      */
  1172.     public function getCountryId(): ?string
  1173.     {
  1174.         return $this->countryId;
  1175.     }
  1176.     /**
  1177.      * @param string|null $countryId
  1178.      */
  1179.     public function setCountryId(?string $countryId): void
  1180.     {
  1181.         $this->countryId $countryId;
  1182.     }
  1183.     /**
  1184.      * @return string|null
  1185.      */
  1186.     public function getFormattedAddress(): ?string
  1187.     {
  1188.         if ($this->getCountryId()) {
  1189.             $address $this->getCountryId();
  1190.             $addressArr = [
  1191.                 $this->getState(),
  1192.                 $this->getCity(),
  1193.                 $this->getZip(),
  1194.                 $this->getAddress(),
  1195.             ];
  1196.             foreach ($addressArr as $value) {
  1197.                 if ($value) {
  1198.                     $address .= ', ' $value;
  1199.                 }
  1200.             }
  1201.         } else {
  1202.             $address $this->getAddress();
  1203.         }
  1204.         return $address;
  1205.     }
  1206.     /**
  1207.      * @return float|null
  1208.      */
  1209.     public function getLat(): ?float
  1210.     {
  1211.         return $this->lat;
  1212.     }
  1213.     /**
  1214.      * @param float|null $lat
  1215.      */
  1216.     public function setLat(?float $lat): void
  1217.     {
  1218.         $this->lat $lat;
  1219.     }
  1220.     /**
  1221.      * @return float|null
  1222.      */
  1223.     public function getLng(): ?float
  1224.     {
  1225.         return $this->lng;
  1226.     }
  1227.     /**
  1228.      * @param float|null $lng
  1229.      */
  1230.     public function setLng(?float $lng): void
  1231.     {
  1232.         $this->lng $lng;
  1233.     }
  1234.     /**
  1235.      * @param string|null $otherCategory
  1236.      */
  1237.     public function setOtherCategory(?string $otherCategory): void
  1238.     {
  1239.         $this->otherCategory $otherCategory;
  1240.     }
  1241.     /**
  1242.      * @return string|null
  1243.      */
  1244.     public function getOtherCategory(): ?string
  1245.     {
  1246.         return $this->otherCategory;
  1247.     }
  1248.     /**
  1249.      * @param bool|null $showAddressInEmail
  1250.      */
  1251.     public function setShowAddressInEmail(?bool $showAddressInEmail): void
  1252.     {
  1253.         $this->showAddressInEmail = !!$showAddressInEmail;
  1254.     }
  1255.     /**
  1256.      * @return bool
  1257.      */
  1258.     public function isShowAddressInEmail(): bool
  1259.     {
  1260.         return !!$this->showAddressInEmail;
  1261.     }
  1262.     /**
  1263.      * @return UserDTO
  1264.      */
  1265.     public function toDTO(): UserDTO
  1266.     {
  1267.         return $this->createUserDto(UserDTO::class);
  1268.     }
  1269.     /**
  1270.      * @return SimpleUserDTO
  1271.      */
  1272.     public function toSimpleDTO(): SimpleUserDTO
  1273.     {
  1274.         return new SimpleUserDTO(
  1275.             $this->getId(),
  1276.             $this->getEmail(),
  1277.             $this->getFullName()
  1278.         );
  1279.     }
  1280.     /**
  1281.      * @return CustomerDetailedDTO
  1282.      */
  1283.     public function toCustomerDto(): CustomerDetailedDTO
  1284.     {
  1285.         $dto $this->createUserDto(CustomerDetailedDTO::class);
  1286.         // todo add email limit here
  1287.         //$dto->addCustomerLimit(new CustomerLimitDTO(UserLimitType::TYPE_EMAIL, $this->getUserEmailLimit()));
  1288.         $expr Criteria::expr();
  1289.         $criteria Criteria::create();
  1290.         $criteria->andWhere($expr->eq('enabled'true));
  1291.         /** @var SubscriptionInterface $subscription */
  1292.         foreach ($this->subscriptions->matching($criteria) as $subscription) {
  1293.             $dto->addCustomerSubscription($subscription->toCustomerSubscriptionDTO());
  1294.             if ($subscription->isValid() && $subscription->isEnabled()) {
  1295.                 $dto->withActiveSubscription(true);
  1296.             }
  1297.         }
  1298.         return $dto;
  1299.     }
  1300.     /**
  1301.      * @return bool
  1302.      */
  1303.     public function isSsoLoginAllowed(): bool
  1304.     {
  1305.         return $this->userSso instanceof UserSsoEntity && $this->userSso->getLoginType() !== UserSsoLoginType::TYPE_PASSWORD;
  1306.     }
  1307.     /**
  1308.      * @param bool $ssoLoginAllowed
  1309.      */
  1310.     public function setSsoLoginAllowed(bool $ssoLoginAllowed): void
  1311.     {
  1312.         if (!$this->userSso) {
  1313.             $this->userSso = new UserSsoEntity(UserSsoLoginType::TYPE_PASSWORD$this);
  1314.         }
  1315.         if ($this->userSso->getLoginType() !== UserSsoLoginType::TYPE_SSO) {
  1316.             if ($ssoLoginAllowed) {
  1317.                 $this->userSso->setLoginType(UserSsoLoginType::TYPE_SSO_PASSWORD);
  1318.             } else {
  1319.                 $this->userSso->setLoginType(UserSsoLoginType::TYPE_PASSWORD);
  1320.             }
  1321.         }
  1322.     }
  1323.     /**
  1324.      * @return bool
  1325.      */
  1326.     public function isOnlySsoUser(): bool
  1327.     {
  1328.         return $this->getUserSso() && $this->getUserSso()->getLoginType() === UserSsoLoginType::TYPE_SSO;
  1329.     }
  1330.     /**
  1331.      * @param string|null $lastTwoFactorCode
  1332.      */
  1333.     public function setLastTwoFactorCode(?string $lastTwoFactorCode): void
  1334.     {
  1335.         $this->lastTwoFactorCode $lastTwoFactorCode;
  1336.     }
  1337.     /**
  1338.      * @return string|null
  1339.      */
  1340.     public function getLastTwoFactorCode(): ?string
  1341.     {
  1342.         return $this->lastTwoFactorCode;
  1343.     }
  1344.     /**
  1345.      * @return Collection|null
  1346.      */
  1347.     public function getUserOAuth(): ?Collection
  1348.     {
  1349.         return $this->userOAuth;
  1350.     }
  1351.     /**
  1352.      * @param string $provider
  1353.      * @return bool
  1354.      */
  1355.     public function hasOAuthProvider(string $provider): bool
  1356.     {
  1357.         $criteria Criteria::create()->where(Criteria::expr()->eq('provider'$provider));
  1358.         return (bool)$this->userOAuth->matching($criteria)->count();
  1359.     }
  1360.     /**
  1361.      * @param string $provider
  1362.      * @return UserOAuthEntity|null
  1363.      */
  1364.     public function getOAuthProvider(string $provider): ?UserOAuthEntity
  1365.     {
  1366.         $criteria Criteria::create()->where(Criteria::expr()->eq('provider'$provider));
  1367.         $oauthProvider $this->userOAuth->matching($criteria)->first();
  1368.         return $oauthProvider ?: null;
  1369.     }
  1370.     /**
  1371.      * @return UserEmailUnsubscribeEntity|null
  1372.      */
  1373.     public function getUserEmailUnsubscribe(): ?UserEmailUnsubscribeEntity
  1374.     {
  1375.         return $this->userEmailUnsubscribe;
  1376.     }
  1377.     /**
  1378.      * @param UserCancellationPolicyEntity|null $userCancellationPolicy
  1379.      */
  1380.     public function setUserCancellationPolicy(?UserCancellationPolicyEntity $userCancellationPolicy): void
  1381.     {
  1382.         $this->userCancellationPolicy $userCancellationPolicy;
  1383.         $this->userCancellationPolicy->setUser($this);
  1384.     }
  1385.     /**
  1386.      * @return UserCancellationPolicyEntity|null
  1387.      */
  1388.     public function getUserCancellationPolicy(): ?UserCancellationPolicyEntity
  1389.     {
  1390.         return $this->userCancellationPolicy;
  1391.     }
  1392.     /**
  1393.      * @return UserWidgetEntity|null
  1394.      */
  1395.     public function getUserWidget(): ?UserWidgetEntity
  1396.     {
  1397.         return $this->userWidget;
  1398.     }
  1399.     /**
  1400.      * @return string
  1401.      */
  1402.     public function getObjectName(): string
  1403.     {
  1404.         return $this->getEmail() . ' (' $this->getSlug() . ')';
  1405.     }
  1406.     /**
  1407.      * @return string
  1408.      */
  1409.     public function getObjectId(): string
  1410.     {
  1411.         return (string)$this->getid();
  1412.     }
  1413.     /**
  1414.      * Get current active subscriptions
  1415.      *
  1416.      * @param bool $withOrganisationSubscription
  1417.      * @return array
  1418.      */
  1419.     public function getCurrentSubscriptions(bool $withOrganisationSubscription true): array
  1420.     {
  1421.         $res = [];
  1422.         if ($this->getDefaultOrganization()) {
  1423.             /** @var Member $owner */
  1424.             foreach ($this->getDefaultOrganization()->getOwners() as $owner) {
  1425.                 $res array_merge($res$owner->getUser()->getPaidSubscriptions());
  1426.             }
  1427.             return $res;
  1428.         }
  1429.         $expr Criteria::expr();
  1430.         $criteria Criteria::create();
  1431.         $criteria
  1432.             ->andWhere($expr->eq('enabled'true))
  1433.             //->andWhere($expr->eq('status', 'active'))
  1434.             ->andWhere($expr->gte('expireAt', new DateTimeImmutable()))
  1435.             ->andWhere($expr->lte('startDate', new DateTimeImmutable()));
  1436.         return array_merge($res$this->subscriptions->matching($criteria)->toArray());
  1437.     }
  1438.     /**
  1439.      * Return user id for subscription
  1440.      *
  1441.      * @return string
  1442.      */
  1443.     public function getSubscriptionUserId(): string
  1444.     {
  1445.         if ($this->getDefaultOrganization()) {
  1446.             /** @var Member $owner */
  1447.             foreach ($this->getDefaultOrganization()->getOwners() as $owner) {
  1448.                 if ($owner->getUser()->hasPaidSubscription()) {
  1449.                     return (string) $owner->getUser()->getId();
  1450.                 }
  1451.             }
  1452.         }
  1453.         return (string) $this->getId();
  1454.     }
  1455.     /**
  1456.      * Return subscription user
  1457.      *
  1458.      * @return UserInterface
  1459.      */
  1460.     public function getSubscriptionUser(): UserInterface
  1461.     {
  1462.         if ($this->getDefaultOrganization()) {
  1463.             /** @var Member $owner */
  1464.             foreach ($this->getDefaultOrganization()->getOwners() as $owner) {
  1465.                 if ($owner->getUser()->hasPaidSubscription()) {
  1466.                     return $owner->getUser();
  1467.                 }
  1468.             }
  1469.         }
  1470.         return $this;
  1471.     }
  1472.     /**
  1473.      * Get user paid subscriptions
  1474.      *
  1475.      * @return array
  1476.      */
  1477.     private function getPaidSubscriptions(): array
  1478.     {
  1479.         $expr Criteria::expr();
  1480.         $criteria Criteria::create();
  1481.         $criteria
  1482.             ->andWhere($expr->eq('enabled'true))
  1483.             //->andWhere($expr->eq('status', 'active'))
  1484.             ->andWhere($expr->gte('expireAt', new DateTimeImmutable()))
  1485.             ->andWhere($expr->lte('startDate', new DateTimeImmutable()))
  1486.             ->andWhere($expr->eq('free'false));
  1487.         return $this->getSubscriptions()->matching($criteria)->toArray();
  1488.     }
  1489.     /**
  1490.      * @return Collection
  1491.      */
  1492.     public function getSubscriptions(): Collection
  1493.     {
  1494.         return $this->subscriptions;
  1495.     }
  1496.     /**
  1497.      * Get current active subscriptions users limit
  1498.      *
  1499.      * @return int
  1500.      */
  1501.     public function getSubscriptionUsersLimit(): int
  1502.     {
  1503.         $res 0;
  1504.         /** @var SubscriptionInterface $subscription */
  1505.         foreach ($this->getCurrentSubscriptions() as $subscription) {
  1506.             $res += $subscription->getUsersTotal();
  1507.         }
  1508.         return $res;
  1509.     }
  1510.     /**
  1511.      * Get current active subscriptions bookings limit
  1512.      *
  1513.      * @return int
  1514.      */
  1515.     public function getSubscriptionBookingsLimit(): int
  1516.     {
  1517.         $res 0;
  1518.         /** @var SubscriptionInterface $subscription */
  1519.         foreach ($this->getCurrentSubscriptions() as $subscription) {
  1520.             $res += $subscription->getBookingsTotal();
  1521.         }
  1522.         return $res;
  1523.     }
  1524.     /**
  1525.      * Has paid subscription
  1526.      *
  1527.      * @param bool $skipTrial
  1528.      * @return bool
  1529.      */
  1530.     public function hasPaidSubscription(bool $skipTrial false): bool
  1531.     {
  1532.         /** @var SubscriptionInterface $subscription */
  1533.         foreach ($this->getCurrentSubscriptions() as $subscription) {
  1534.             if (!$subscription->isFree()) {
  1535.                 if ($skipTrial && $subscription->isTrial()) {
  1536.                     continue;
  1537.                 }
  1538.                 return true;
  1539.             }
  1540.         }
  1541.         return false;
  1542.     }
  1543.     /**
  1544.      * @return bool
  1545.      */
  1546.     public function hasTrialSubscription(): bool
  1547.     {
  1548.         return !empty($this->getTrialSubscriptions());
  1549.     }
  1550.     /**
  1551.      * @return array
  1552.      */
  1553.     public function getTrialSubscriptions(): array
  1554.     {
  1555.         $res = [];
  1556.         $expr Criteria::expr();
  1557.         $criteria Criteria::create();
  1558.         $criteria->andWhere($expr->eq('trial'true));
  1559.         $organization $this->getDefaultOrganization();
  1560.         if ($organization) {
  1561.             /** @var Member $owner */
  1562.             foreach ($organization->getOwners() as $owner) {
  1563.                 $res array_merge($res$owner->getUser()->subscriptions->matching($criteria)->toArray());
  1564.             }
  1565.             return $res;
  1566.         }
  1567.         return array_merge($res$this->subscriptions->matching($criteria)->toArray());
  1568.     }
  1569.     /**
  1570.      * Is main owner
  1571.      *
  1572.      * @return bool
  1573.      */
  1574.     public function isMainOwner(): bool
  1575.     {
  1576.         if ($this->getDefaultOrganization()) {
  1577.             /** @var Member $member */
  1578.             foreach ($this->getMembers() as $member) {
  1579.                 if ($member->getOrganization()->getId() === $this->getDefaultOrganization()->getId() && $member->getIsMainOwner()) {
  1580.                     return true;
  1581.                 }
  1582.             }
  1583.         }
  1584.         return false;
  1585.     }
  1586.     public function isOwner(): bool
  1587.     {
  1588.         if ($this->getDefaultOrganization()) {
  1589.             return $this->getDefaultOrganization()->isOrganizationOwner($this);
  1590.         }
  1591.         return false;
  1592.     }
  1593.     /**
  1594.      * @return UserSocialLinkEntity|null
  1595.      */
  1596.     public function getSocialLink(): ?UserSocialLinkEntity
  1597.     {
  1598.         return $this->socialLink;
  1599.     }
  1600.     /**
  1601.      * @param UserSocialLinkEntity|null $socialLink
  1602.      */
  1603.     public function setSocialLink(?UserSocialLinkEntity $socialLink): void
  1604.     {
  1605.         $this->socialLink $socialLink;
  1606.         $this->socialLink->setUser($this);
  1607.     }
  1608.     /**
  1609.      * @return Collection|UserTaxEntity[]
  1610.      */
  1611.     public function getTax(): Collection
  1612.     {
  1613.         return $this->tax;
  1614.     }
  1615.     /**
  1616.      * @param BaseUserInterface $user
  1617.      * @return bool
  1618.      */
  1619.     public function isEqualTo(BaseUserInterface $user)
  1620.     {
  1621.         $isEqualTo parent::isEqualTo($user);
  1622.         if ($user->isEnabled() !== $this->isEnabled()) {
  1623.             $isEqualTo false;
  1624.         }
  1625.         return $isEqualTo;
  1626.     }
  1627.     /**
  1628.      * @return Collection
  1629.      */
  1630.     public function getRelatedUsers(): Collection
  1631.     {
  1632.         return $this->relatedUsers;
  1633.     }
  1634.     /**
  1635.      * @param UserRelationEntity $relatedUser
  1636.      */
  1637.     public function addRelatedUser(UserRelationEntity $relatedUser): void
  1638.     {
  1639.         if (!$this->relatedUsers->contains($relatedUser)) {
  1640.             $this->relatedUsers->add($relatedUser);
  1641.         }
  1642.     }
  1643.     /**
  1644.      * @return array|UserInterface[]
  1645.      */
  1646.     public function getChildRelatedUsers(): array
  1647.     {
  1648.         $result = [];
  1649.         foreach ($this->relatedUsers as $relatedUser) {
  1650.             $result[] = $relatedUser->getChildUser();
  1651.         }
  1652.         return $result;
  1653.     }
  1654.     /**
  1655.      * @param UserRelationEntity $entity
  1656.      * @return bool
  1657.      */
  1658.     public function hasChildRelatedUser(UserRelationEntity $entity): bool
  1659.     {
  1660.         foreach ($this->relatedUsers as $relatedUser) {
  1661.             if ($relatedUser->getChildUser() === $entity->getChildUser()) {
  1662.                 return true;
  1663.             }
  1664.         }
  1665.         return false;
  1666.     }
  1667.     /**
  1668.      * @return string|null
  1669.      */
  1670.     public function getWelcomeTourStep(): ?string
  1671.     {
  1672.         return $this->welcomeTourStep;
  1673.     }
  1674.     /**
  1675.      * @param string|null $welcomeTourStep
  1676.      */
  1677.     public function setWelcomeTourStep(?string $welcomeTourStep): void
  1678.     {
  1679.         $this->welcomeTourStep $welcomeTourStep;
  1680.     }
  1681.     /**
  1682.      * @return bool
  1683.      */
  1684.     public function isSecondFactorSkipped(): bool
  1685.     {
  1686.         return $this->secondFactorSkipped;
  1687.     }
  1688.     /**
  1689.      * @param bool $secondFactorSkipped
  1690.      */
  1691.     public function setSecondFactorSkipped(bool $secondFactorSkipped): void
  1692.     {
  1693.         $this->secondFactorSkipped $secondFactorSkipped;
  1694.     }
  1695.     /**
  1696.      * @return bool
  1697.      */
  1698.     public function isTutorialSkipped(): bool
  1699.     {
  1700.         $releaseDate = new DateTimeImmutable('2024-09-23');
  1701.         $oneMonthAfterRegistration = clone $this->createdAt;
  1702.         $oneMonthAfterRegistration $oneMonthAfterRegistration->modify('+1 month');
  1703.         // Check if the user registered after the release date and is within the first month of registration
  1704.         $isNewUser $this->createdAt $releaseDate;
  1705.         $isWithinFirstMonth = new DateTimeImmutable() <= $oneMonthAfterRegistration;
  1706.         // Return true if the tutorial has been skipped, or the user is not a new user, or if the one-month period has passed
  1707.         return $this->tutorialSkipped || !$isNewUser || !$isWithinFirstMonth;
  1708.     }
  1709.     /**
  1710.      * @return void
  1711.      */
  1712.     public function skipTutorial(): void
  1713.     {
  1714.         $this->tutorialSkipped true;
  1715.     }
  1716.     /**
  1717.      * {@inheritdoc}
  1718.      */
  1719.     public function serialize()
  1720.     {
  1721.         return serialize([
  1722.             $this->password,
  1723.             $this->salt,
  1724.             $this->usernameCanonical,
  1725.             $this->username,
  1726.             $this->enabled,
  1727.             $this->id,
  1728.             $this->email,
  1729.             $this->emailCanonical,
  1730.             $this->address,
  1731.             $this->state,
  1732.             $this->city,
  1733.             $this->zip,
  1734.             $this->countryId,
  1735.             $this->lat,
  1736.             $this->lng,
  1737.             $this->brandingEnabled,
  1738.             $this->showAddressInEmail,
  1739.             $this->fullName,
  1740.             $this->timezone,
  1741.             $this->timeFormat,
  1742.             $this->dateFormat,
  1743.             $this->userSso,
  1744.             $this->otherCategory,
  1745.         ]);
  1746.     }
  1747.     /**
  1748.      * {@inheritdoc}
  1749.      */
  1750.     public function unserialize($serialized)
  1751.     {
  1752.         $data unserialize($serialized);
  1753.         [
  1754.             $this->password,
  1755.             $this->salt,
  1756.             $this->usernameCanonical,
  1757.             $this->username,
  1758.             $this->enabled,
  1759.             $this->id,
  1760.             $this->email,
  1761.             $this->emailCanonical,
  1762.             $this->address,
  1763.             $this->state,
  1764.             $this->city,
  1765.             $this->zip,
  1766.             $this->countryId,
  1767.             $this->lat,
  1768.             $this->lng,
  1769.             $this->brandingEnabled,
  1770.             $this->showAddressInEmail,
  1771.             $this->fullName,
  1772.             $this->timezone,
  1773.             $this->timeFormat,
  1774.             $this->dateFormat,
  1775.             $this->userSso,
  1776.             $this->otherCategory,
  1777.         ] = $data;
  1778.     }
  1779.     /**
  1780.      * @param string $class
  1781.      * @return UserDto|CustomerDetailedDTO
  1782.      */
  1783.     private function createUserDto(string $class): object
  1784.     {
  1785.         $phone $this->getInternationalPhoneNumber();
  1786.         $organization $this->getDefaultOrganization();
  1787.         $connections = [];
  1788.         foreach ($this->userOAuth as $userOAuth) {
  1789.             $connections[] = $userOAuth->getProvider();
  1790.         }
  1791.         try {
  1792.             $timezone $this->getTimezone() ?? 'UTC';
  1793.             $currentDate = new DateTimeImmutable('now', new DateTimeZone($timezone));
  1794.             $timezoneOffset $currentDate->format('P');
  1795.         } catch (Exception $e) {
  1796.             $timezone 'UTC';
  1797.             $timezoneOffset '+00:00';
  1798.         }
  1799.         return new $class(
  1800.             $this->getId(),
  1801.             $this->getUuid(),
  1802.             $this->getEmail(),
  1803.             $this->getFullName(),
  1804.             $this->getSlug(),
  1805.             $this->getSubscriptionUsersLimit(),
  1806.             count($this->getAllowedSecondAuthenticationTypes()) > 0,
  1807.             $this->isEnabled(),
  1808.             $this->hasPaidSubscription(),
  1809.             $this->getDateFormat(),
  1810.             $this->getTimeFormat(),
  1811.             $timezone,
  1812.             $timezoneOffset,
  1813.             $this->getAddress(),
  1814.             $this->getState(),
  1815.             $this->getCity(),
  1816.             $this->getZip(),
  1817.             $this->getCountryId(),
  1818.             $this->getLat(),
  1819.             $this->getLng(),
  1820.             $this->getDomain(),
  1821.             $phone ?: null,
  1822.             $this->getCompanyLogoName(),
  1823.             $this->getAvatarName(),
  1824.             $organization $organization->toDTO() : null,
  1825.             $this->getCreatedAt(),
  1826.             $this->getLastLogin(),
  1827.             $connections
  1828.         );
  1829.     }
  1830. }