src/App/Entity/User.php line 43

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Entity\ConversationMessage\ConversationMessageAttachmentFile;
  4. use App\Entity\ExternalPartner\ExternalPartner;
  5. use App\Entity\ExternalPartner\IntegratedExternalPartnerCustomer;
  6. use App\Entity\ExternalPartner\UserAdditionalInfo;
  7. use App\Entity\Membership\BillwerkContract;
  8. use App\Entity\Membership\RecurrentJobBooking;
  9. use App\Entity\Profile\JoboffererProfile;
  10. use App\Entity\Profile\JobseekerProfile;
  11. use App\Exception\InvalidEmailException;
  12. use App\Service\MailService;
  13. use App\Service\Membership\BillwerkSynchronizationService;
  14. use App\Utility\DateTimeUtility;
  15. use App\Utility\ReflectionHelper;
  16. use DateTime;
  17. use Doctrine\Common\Collections\ArrayCollection;
  18. use Doctrine\Common\Collections\Collection;
  19. use Doctrine\ORM\Mapping as ORM;
  20. use Exception;
  21. use FOS\UserBundle\Model\User as FOSUser;
  22. use FrontendSpaApi\Entity\ApiKey as FrontendSpaApiKey;
  23. use InvalidArgumentException;
  24. use JanusHercules\Membership\Domain\Entity\FlexMembershipRecurrentJobSlot;
  25. use MobileAppApi\Entity\ApiKey as MobileAppApiKey;
  26. use Symfony\Component\Validator\Constraints as Assert;
  27. /**
  28. * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
  29. *
  30. * @ORM\Table(
  31. * name="users",
  32. * indexes={
  33. *
  34. * @ORM\Index(name="created_at_idx", columns={"created_at"}),
  35. * @ORM\Index(name="email_idx", columns={"email"}),
  36. * @ORM\Index(name="username_idx", columns={"username"})
  37. * }
  38. * )
  39. */
  40. class User extends FOSUser
  41. {
  42. public const string ROLE_NAME_JOBOFFERER = 'ROLE_JOBOFFERER';
  43. public const string ROLE_NAME_JOBSEEKER = 'ROLE_JOBSEEKER';
  44. public const string ROLE_NAME_ADMIN = 'ROLE_ADMIN';
  45. // Can access all admin areas, but cannot modify or delete stuff
  46. public const string ROLE_NAME_ADMIN_READONLY = 'ROLE_ADMIN_READONLY';
  47. // Can access the user admin page only, and cannot modify or delete users there
  48. public const string ROLE_NAME_ADMIN_PROFILEVERIFIER = 'ROLE_ADMIN_PROFILEVERIFIER';
  49. // Only users with this role are allowed to change data related to content distribution (e.g. CPC info in feeds)
  50. public const string ROLE_NAME_ADMIN_CONTENT_DISTRIBUTION = 'ROLE_ADMIN_CONTENT_DISTRIBUTION';
  51. // Only users with this role are allowed to modify data on blacklisting portal
  52. public const string ROLE_NAME_ADMIN_BLACKLISTING = 'ROLE_ADMIN_BLACKLISTING';
  53. public const string ROLE_NAME_ADMIN_USER_CREATOR = 'ROLE_ADMIN_USER_CREATOR';
  54. // No admin rights, but flagged features are "on" for users with this role
  55. public const string ROLE_NAME_EXTERNAL_FEATURE_TESTER = 'ROLE_EXTERNAL_FEATURE_TESTER';
  56. // No admin rights, but can browse wanted jobs and other stuff through a dedicated interface
  57. public const string ROLE_NAME_NAVIGATOR = 'ROLE_NAVIGATOR';
  58. // No admin rights, but can browse the quota portal
  59. public const string ROLE_NAME_INTEGRATED_EXTERNAL_PARTNER_MANAGER = 'ROLE_INTEGRATED_EXTERNAL_PARTNER_MANAGER';
  60. // For normal jobofferer users that "simulate" an external partner (e.g. by linking external application urls)
  61. public const string ROLE_NAME_QUASI_EXTERNAL_PARTNER = 'ROLE_QUASI_EXTERNAL_PARTNER';
  62. public const string ROLE_NAME_CUSTOMER_SPECIFIC_EXTERNAL_PARTNER_EVENT_AGGREGATIONS_READER = 'ROLE_CUSTOMER_SPECIFIC_EXTERNAL_PARTNER_EVENT_AGGREGATIONS_READER';
  63. public const string ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_READER = 'ROLE_SPECIFIC_CUSTOMER_CAMPAIGNS_READER';
  64. public const string ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_WRITER = 'ROLE_SPECIFIC_CUSTOMER_CAMPAIGNS_WRITER';
  65. public const string ROLE_NAME_SPECIFIC_CUSTOMER_GAUGES_READER = 'ROLE_SPECIFIC_CUSTOMER_GAUGES_READER';
  66. public const string ROLE_NAME_EXTERNAL_JOB_POSTING_CRAWLER_MANAGER = 'ROLE_EXTERNAL_JOB_POSTING_CRAWLER_MANAGER';
  67. public const string ROLE_NAME_SALES_RECRUITER = 'ROLE_SALES_RECRUITER';
  68. public const string ROLE_NAME_RECURRENT_JOBS_MANAGER = 'ROLE_RECURRENT_JOBS_MANAGER';
  69. public const string ROLE_NAME_AGENTUR_FUER_ARBEIT_MANAGER = 'ROLE_AGENTUR_FUER_ARBEIT_MANAGER';
  70. public const string ROLE_NAME_SELF_SERVICE_CAMPAIGN_ADMIN = 'ROLE_SELF_SERVICE_CAMPAIGN_ADMIN';
  71. public const string ROLE_NAME_MEMBERSHIP_ACTIONS_TESTER = 'ROLE_MEMBERSHIP_ACTIONS_TESTER';
  72. public const string ROLE_NAME_APPLICATION_APPOINTMENT_SCHEDULING_MANAGER = 'ROLE_APPLICATION_APPOINTMENT_SCHEDULING_MANAGER';
  73. public const string ROLE_NAME_APPLICATION_APPOINTMENT_SCHEDULING_MANAGER_READONLY = 'ROLE_APPLICATION_APPOINTMENT_SCHEDULING_MANAGER_READONLY';
  74. public const int USER_TYPE_JOBOFFERER = 0;
  75. public const int USER_TYPE_JOBSEEKER = 1;
  76. public const int CREATED_VIA_JOBOO_REGISTRATION = 0;
  77. public const int CREATED_VIA_RECRUIT_DL_RECURRENT_JOB_LANDINGPAGE = 1;
  78. public const int CREATED_VIA_AN_EXTERNAL_PARTNER_SERVICE = 8;
  79. public const int CREATED_VIA_RECURRENT_JOBS_MASS_EDITOR = 11;
  80. public const int CREATED_VIA_JOBOO_RECURRENT_JOB_LANDINGPAGE = 12;
  81. public const int CREATED_VIA_JOBOO_ONLINE_RECURRENT_JOB_LANDINGPAGE = 14;
  82. public const int CREATED_VIA_GOOGLE_IDENTITY_OAUTH2 = 16;
  83. public const int CREATED_VIA_GOOGLE_IDENTITY_GSI = 17;
  84. public const int CREATED_VIA_MOBILE_APP = 22;
  85. public const int CREATED_VIA_FACEBOOK_LEAD_USER_CREATION = 23;
  86. public const int CREATED_VIA_CAMPAIGN_WUNSCHJOBS_JOBSEEKER_FLOW = 24;
  87. public const int CREATED_VIA_DIGITAL_ESTATE_CONTENT = 25;
  88. public const int CREATED_VIA_INCOMING_APPLICATION_PERSPECTIVE = 26;
  89. public const int CREATED_VIA_INCOMING_REGISTRATION_PERSPECTIVE = 27;
  90. public const int CREATED_VIA_WANTED_JOBS_SEARCH_ANONYMOUS_USER_FORM = 28;
  91. public const int CREATED_VIA_RECURRENT_JOB_DETAILPAGE_ANONYMOUS_USER = 29;
  92. public const int CREATED_VIA_APPLICATION_APPOINTMENT_SCHEDULING_SERVICE = 30;
  93. public const int CREATED_VIA_ACTIVATE_JOBRADAR_IN_ANONYMOUS_JOB_SEARCH = 31;
  94. public const int CREATED_VIA_CUSTOMER_LANDINGPAGE_ANONYMOUS_USER = 32;
  95. public const int CREATED_VIA_EMAIL_QUICK_REGISTRATION = 33;
  96. /**
  97. * @throws Exception
  98. */
  99. public function __construct(?string $id = null)
  100. {
  101. parent::__construct();
  102. if (!is_null($id)) {
  103. $this->id = $id;
  104. }
  105. $this->setIsGoGastro(false);
  106. $this->setIsLockedByAdmin(false);
  107. $this->jobseekerProfiles = new ArrayCollection();
  108. $this->joboffererProfiles = new ArrayCollection();
  109. $this->onetimeLoginTokens = new ArrayCollection();
  110. $this->notificationSettings = new ArrayCollection();
  111. $this->createdAt = DateTimeUtility::createDateTimeUtc();
  112. $this->createdVia = self::CREATED_VIA_JOBOO_REGISTRATION;
  113. $this->billwerkContracts = new ArrayCollection();
  114. $this->emailDeliveryNotifications = new ArrayCollection();
  115. $this->notificationStates = new ArrayCollection();
  116. $this->externalPartnerUserAdditionalInfos = new ArrayCollection();
  117. $this->cleverpushSubscriptions = new ArrayCollection();
  118. $this->mobileAppApiKeys = new ArrayCollection();
  119. $this->frontendSpaApiKeys = new ArrayCollection();
  120. $this->integratedExternalPartnerCustomers = new ArrayCollection();
  121. $this->recurrentJobBookings = new ArrayCollection();
  122. $this->userAdditionalInfos = new ArrayCollection();
  123. $this->recurrentJobSlots = new ArrayCollection();
  124. }
  125. /**
  126. * @ORM\GeneratedValue(strategy="CUSTOM")
  127. *
  128. * @ORM\CustomIdGenerator(class="App\Utility\DatabaseIdGenerator")
  129. *
  130. * @ORM\Column(name="id", type="guid")
  131. *
  132. * @ORM\Id
  133. */
  134. protected $id;
  135. public function getId(): ?string
  136. {
  137. return $this->id;
  138. }
  139. /**
  140. * @var bool
  141. *
  142. * @ORM\Column(name="is_go_gastro", type="boolean", nullable=false)
  143. */
  144. protected $isGoGastro;
  145. public function isGoGastro(): bool
  146. {
  147. return $this->isGoGastro;
  148. }
  149. public function setIsGoGastro(bool $isGoGastro): void
  150. {
  151. $this->isGoGastro = $isGoGastro;
  152. }
  153. /**
  154. * @Assert\Email(
  155. * mode="strict",
  156. * groups={"Registration"}
  157. * )
  158. */
  159. protected $email;
  160. /**
  161. * @var DateTime
  162. *
  163. * @ORM\Column(name="created_at", type="datetime", nullable=false)
  164. */
  165. protected $createdAt;
  166. /**
  167. * @return DateTime
  168. */
  169. public function getCreatedAt()
  170. {
  171. return $this->createdAt;
  172. }
  173. public function setCreatedAt(DateTime $createdAt)
  174. {
  175. $this->createdAt = $createdAt;
  176. }
  177. /**
  178. * @var bool
  179. *
  180. * @ORM\Column(name="created_via", type="integer", nullable=false)
  181. */
  182. protected $createdVia;
  183. /** @throws Exception */
  184. public function setCreatedVia(int $createdVia): void
  185. {
  186. if (!ReflectionHelper::hasConstWithValue(self::class, 'CREATED_VIA_', $createdVia)) {
  187. throw new Exception("Not a valid value for createdVia: '{$createdVia}'.");
  188. }
  189. $this->createdVia = $createdVia;
  190. }
  191. public function getCreatedVia(): int
  192. {
  193. return $this->createdVia;
  194. }
  195. /**
  196. * @var ?DateTime
  197. *
  198. * @ORM\Column(name="lastseen_at", type="datetime", nullable=true)
  199. */
  200. protected $lastseenAt;
  201. public function getLastseenAt(): ?DateTime
  202. {
  203. return $this->lastseenAt;
  204. }
  205. public function setLastseenAt(?DateTime $lastseenAt)
  206. {
  207. $this->lastseenAt = $lastseenAt;
  208. }
  209. /**
  210. * @var ExternalPartner|null
  211. *
  212. * @ORM\ManyToOne(targetEntity="App\Entity\ExternalPartner\ExternalPartner", inversedBy="users", cascade={"persist"})
  213. *
  214. * @ORM\JoinColumn(name="external_partners_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
  215. */
  216. protected $externalPartner;
  217. public function getExternalPartner(): ?ExternalPartner
  218. {
  219. return $this->externalPartner;
  220. }
  221. /** @throws Exception */
  222. public function setExternalPartner(?ExternalPartner $externalPartner, bool $mustBeJobofferer = true): void
  223. {
  224. if (!is_null($externalPartner) && $mustBeJobofferer && !$this->isJobofferer()) {
  225. throw new Exception("Setting an external partner on user {$this->getId()} is not possible because this user is not a jobofferer.");
  226. }
  227. if (!is_null($externalPartner)) {
  228. foreach ($this->getJoboffererProfiles() as $joboffererProfile) {
  229. foreach ($joboffererProfile->getRecurrentJobs() as $recurrentJob) {
  230. if (!is_null($recurrentJob->getQuota())) {
  231. if ($recurrentJob->getQuota()->getIntegratedExternalPartnerCustomer()->getExternalPartner()->getId() !== $externalPartner->getId()) {
  232. throw new Exception("Setting the external partner {$externalPartner->getId()} on user {$this->getId()} is not possible because this user has a recurrent job with a quota linked to external partner {$recurrentJob->getQuota()->getIntegratedExternalPartnerCustomer()->getExternalPartner()->getId()}.");
  233. }
  234. }
  235. }
  236. }
  237. }
  238. $this->externalPartner = $externalPartner;
  239. }
  240. /**
  241. * @ORM\ManyToMany(targetEntity="App\Entity\ExternalPartner\IntegratedExternalPartnerCustomer")
  242. *
  243. * @ORM\JoinTable(name="users_integrated_external_partner_customers",
  244. * joinColumns={@ORM\JoinColumn(name="users_id", referencedColumnName="id", unique=true)},
  245. * inverseJoinColumns={@ORM\JoinColumn(name="integrated_external_partner_customers_id", referencedColumnName="id", onDelete="CASCADE")}
  246. * )
  247. *
  248. * Note: The naming here is potentially misleading.
  249. * A user can only be linked to exactly zero or exactly one integrated external partner customer,
  250. * but not to multiple integrated external partner customers!
  251. *
  252. * The reason that $integratedExternalPartnerCustomers is a "plural" collection is only
  253. * due to the fact that upon implementation of this relationship, we wanted to avoid extending
  254. * the large users table with another column, and instead use a separate table.
  255. */
  256. protected Collection $integratedExternalPartnerCustomers;
  257. public function getIntegratedExternalPartnerCustomer(): ?IntegratedExternalPartnerCustomer
  258. {
  259. if ($this->integratedExternalPartnerCustomers->count() === 0) {
  260. return null;
  261. }
  262. return $this->integratedExternalPartnerCustomers->first();
  263. }
  264. /** @throws Exception */
  265. public function setIntegratedExternalPartnerCustomer(?IntegratedExternalPartnerCustomer $customer, bool $mustBeJobofferer = true): void
  266. {
  267. if (!is_null($customer) && $mustBeJobofferer && !$this->isJobofferer()) {
  268. throw new Exception("Setting the integrated external partner customer {$customer->getInternalId()} on user {$this->getId()} is not possible because this user is not a jobofferer.");
  269. }
  270. if (!is_null($customer)) {
  271. foreach ($this->getJoboffererProfiles() as $joboffererProfile) {
  272. foreach ($joboffererProfile->getRecurrentJobs() as $recurrentJob) {
  273. if (!is_null($recurrentJob->getQuota())) {
  274. if ($recurrentJob->getQuota()->getIntegratedExternalPartnerCustomer()->getId() !== $customer->getId()) {
  275. throw new Exception("Setting the integrated external partner customer {$customer->getInternalId()} on user {$this->getId()} is not possible because this user has a recurrent job with a quota linked to customer {$recurrentJob->getQuota()->getIntegratedExternalPartnerCustomer()->getInternalId()}.");
  276. }
  277. }
  278. }
  279. }
  280. }
  281. if (!is_null($this->getExternalPartner())) {
  282. if ($this->getExternalPartner()->getId() !== $customer->getExternalPartner()->getId()) {
  283. throw new Exception("Setting the integrated external partner customer {$customer->getInternalId()} on user {$this->getId()} is not possible because this user is linked to external partner {$this->getExternalPartner()->getId()} while the customer belongs to external partner {$customer->getExternalPartner()->getId()}.");
  284. }
  285. }
  286. $this->integratedExternalPartnerCustomers->clear();
  287. $this->integratedExternalPartnerCustomers->add($customer);
  288. }
  289. /**
  290. * @var JobseekerProfile[]|Collection
  291. *
  292. * @ORM\OneToMany(targetEntity="\App\Entity\Profile\JobseekerProfile", mappedBy="user", cascade={"persist", "remove"})
  293. */
  294. protected $jobseekerProfiles;
  295. public function addJobseekerProfile(JobseekerProfile $jobseekerProfile): void
  296. {
  297. $this->jobseekerProfiles[] = $jobseekerProfile;
  298. }
  299. public function getJobseekerProfiles()
  300. {
  301. return $this->jobseekerProfiles;
  302. }
  303. /**
  304. * @var JoboffererProfile[]|Collection
  305. *
  306. * @ORM\OneToMany(targetEntity="\App\Entity\Profile\JoboffererProfile", mappedBy="user", cascade={"persist", "remove"})
  307. */
  308. protected $joboffererProfiles;
  309. public function addJoboffererProfile(JoboffererProfile $joboffererProfile): void
  310. {
  311. $this->joboffererProfiles[] = $joboffererProfile;
  312. }
  313. public function getJoboffererProfiles()
  314. {
  315. return $this->joboffererProfiles;
  316. }
  317. /**
  318. * @var OnetimeLoginToken|Collection
  319. *
  320. * @ORM\OneToMany(targetEntity="\App\Entity\OnetimeLoginToken", mappedBy="user", cascade={"persist", "remove"})
  321. */
  322. protected $onetimeLoginTokens;
  323. public function addOnetimeLoginToken(OnetimeLoginToken $onetimeLoginToken): void
  324. {
  325. $this->onetimeLoginTokens[] = $onetimeLoginToken;
  326. }
  327. public function getOnetimeLoginTokens()
  328. {
  329. return $this->onetimeLoginTokens;
  330. }
  331. /**
  332. * @var FirebaseToken[]|Collection
  333. *
  334. * @ORM\OneToMany(targetEntity="\App\Entity\FirebaseToken", mappedBy="user", cascade={"persist", "remove"})
  335. */
  336. protected $firebaseTokens;
  337. public function addFirebaseTokens(FirebaseToken $firebaseToken): void
  338. {
  339. $this->firebaseTokens[] = $firebaseToken;
  340. }
  341. public function getFirebaseTokens(): Collection
  342. {
  343. return $this->firebaseTokens;
  344. }
  345. public function canReceiveMobileAppPushNotifications(): bool
  346. {
  347. return
  348. !$this->isLocked()
  349. && !$this->isPaused()
  350. && sizeof($this->firebaseTokens) > 0
  351. ;
  352. }
  353. /**
  354. * @var NotificationSetting|Collection
  355. *
  356. * @ORM\OneToMany(targetEntity="\App\Entity\NotificationSetting", mappedBy="user", cascade={"persist", "remove"})
  357. */
  358. protected $notificationSettings;
  359. public function addNotificationSetting(NotificationSetting $notificationSetting): void
  360. {
  361. $this->notificationSettings[] = $notificationSetting;
  362. }
  363. public function getNotificationSettings()
  364. {
  365. return $this->notificationSettings;
  366. }
  367. /**
  368. * @var NotificationState|Collection
  369. *
  370. * @ORM\OneToMany(targetEntity="\App\Entity\NotificationState", mappedBy="user", cascade={"persist", "remove"})
  371. */
  372. protected $notificationStates;
  373. public function addNotificationState(NotificationState $notificationState): void
  374. {
  375. $this->notificationStates[] = $notificationState;
  376. }
  377. public function getNotificationStates()
  378. {
  379. return $this->notificationStates;
  380. }
  381. /**
  382. * @var ConversationMessageAttachmentFile[]|Collection
  383. *
  384. * @ORM\OneToMany(targetEntity="\App\Entity\ConversationMessage\ConversationMessageAttachmentFile", mappedBy="user", cascade={"persist", "remove"})
  385. */
  386. protected $conversationMessageAttachmentFiles;
  387. /**
  388. * @var CleverpushSubscription[]|Collection|null
  389. *
  390. * @ORM\OneToMany(targetEntity="App\Entity\CleverpushSubscription", mappedBy="user", cascade={"persist", "remove"})
  391. */
  392. protected $cleverpushSubscriptions;
  393. public function getCleverpushSubscriptions()
  394. {
  395. return $this->cleverpushSubscriptions;
  396. }
  397. public function addCleverpushSubscription(CleverpushSubscription $cleverpushSubscription): void
  398. {
  399. $this->cleverpushSubscriptions[] = $cleverpushSubscription;
  400. }
  401. /**
  402. * @var string
  403. *
  404. * @ORM\Column(name="encodedRegistrationCarryThroughData", type="string", length=8192, nullable=true)
  405. */
  406. protected $encodedRegistrationCarryThroughData;
  407. public function setEncodedRegistrationCarryThroughData(string $data): void
  408. {
  409. $this->encodedRegistrationCarryThroughData = $data;
  410. }
  411. public function getEncodedRegistrationCarryThroughData()
  412. {
  413. return $this->encodedRegistrationCarryThroughData;
  414. }
  415. /**
  416. * @var bool
  417. *
  418. * @ORM\Column(name="is_locked_by_admin", type="boolean", nullable=false)
  419. */
  420. protected $isLockedByAdmin;
  421. public function isLockedByAdmin(): bool
  422. {
  423. return $this->isLockedByAdmin;
  424. }
  425. public function setIsLockedByAdmin(bool $isLockedByAdmin)
  426. {
  427. $this->isLockedByAdmin = $isLockedByAdmin;
  428. }
  429. public function isLocked(): bool
  430. {
  431. return $this->isLockedByAdmin;
  432. }
  433. /**
  434. * @var bool
  435. *
  436. * @ORM\Column(name="has_system_generated_password", type="boolean", nullable=false)
  437. */
  438. protected $hasSystemGeneratedPassword;
  439. public function hasSystemGeneratedPassword(): bool
  440. {
  441. return $this->hasSystemGeneratedPassword;
  442. }
  443. public function setHasSystemGeneratedPassword(bool $hasSystemGeneratedPassword): void
  444. {
  445. $this->hasSystemGeneratedPassword = $hasSystemGeneratedPassword;
  446. }
  447. /**
  448. * @var ?string
  449. *
  450. * @ORM\Column(name="billwerk_customer_id", type="text", length=512, nullable=true)
  451. *
  452. * In a sense, this attribute is a bit redundant, but it's still here for historic/backwards-compatibility reasons.
  453. *
  454. * In general, one Joboo User can and will be linked to multiple Billwerk Customers; it's not a 1:1
  455. * relation. This is because our Billwerk order/checkout process currently isn't capable of recognizing
  456. * that a Membership contract is about to get purchased from an already existing Billwerk customer.
  457. *
  458. * This means that every order/checkpout process creates a new Customer at Billwerk.
  459. *
  460. * Also @see BillwerkContract: multiple rows can be linked to the same users_id.
  461. *
  462. * Therefore, this attribute means "the customer of the contract that is currently relevant for us in
  463. * terms of Membership", which in turn is defined as "the customer from the Contract we got
  464. * synced from Billwerk most recently for the first time". In other words: whenever a new "ContractCreated"
  465. * webhook comes in, and whenever a Contract disappears (annulation), this value changes.
  466. *
  467. * @see BillwerkSynchronizationService::mapUserToBillwerkCustomerIdOfLatestContract() to see how this
  468. * attribute is determined and set.
  469. */
  470. protected $billwerkCustomerId;
  471. public function setBillwerkCustomerId(?string $billwerkCustomerId)
  472. {
  473. $this->billwerkCustomerId = $billwerkCustomerId;
  474. }
  475. public function getBillwerkCustomerId(): ?string
  476. {
  477. return $this->billwerkCustomerId;
  478. }
  479. /**
  480. * @var BillwerkContract[]|ArrayCollection|array
  481. *
  482. * @ORM\OneToMany(targetEntity="App\Entity\Membership\BillwerkContract", mappedBy="user", cascade={"persist", "remove"}, fetch="EAGER")
  483. *
  484. * @ORM\OrderBy({"createdAt": "ASC"})
  485. */
  486. protected $billwerkContracts;
  487. /**
  488. * @return BillwerkContract[]|array|ArrayCollection
  489. */
  490. public function getBillwerkContracts()
  491. {
  492. return $this->billwerkContracts;
  493. }
  494. /**
  495. * @param BillwerkContract[]|array|ArrayCollection $billwerkContracts
  496. */
  497. public function setBillwerkContracts($billwerkContracts): void
  498. {
  499. $this->billwerkContracts = $billwerkContracts;
  500. }
  501. /**
  502. * @var ?string
  503. *
  504. * @deprecated This has been deprecated in favor of the MobileAppApiKey[] entity below
  505. *
  506. * @ORM\Column(name="mobile_app_api_key_id", type="text", length=63, nullable=true)
  507. */
  508. protected $mobileAppApiKeyId;
  509. /**
  510. * @var MobileAppApiKey[]|ArrayCollection|array
  511. *
  512. * @ORM\OneToMany(targetEntity="MobileAppApi\Entity\ApiKey", mappedBy="user", cascade={"persist", "remove"}, fetch="EXTRA_LAZY")
  513. */
  514. protected $mobileAppApiKeys;
  515. /** @return MobileAppApiKey[]|ArrayCollection|array */
  516. public function getMobileAppApiKeys(): Collection
  517. {
  518. return $this->mobileAppApiKeys;
  519. }
  520. public function addMobileAppApiKey(MobileAppApiKey $newApiKey): void
  521. {
  522. foreach ($this->mobileAppApiKeys as $apiKey) {
  523. if ($apiKey->getId() === $newApiKey->getId()) {
  524. throw new InvalidArgumentException("A mobile app api key with id '{$apiKey->getId()}' is already attached to this user.");
  525. }
  526. }
  527. $this->mobileAppApiKeys->add($newApiKey);
  528. }
  529. /**
  530. * @var FrontendSpaApiKey[]|ArrayCollection|array
  531. *
  532. * @ORM\OneToMany(targetEntity="FrontendSpaApi\Entity\ApiKey", mappedBy="user", cascade={"persist", "remove"}, fetch="EXTRA_LAZY")
  533. */
  534. protected $frontendSpaApiKeys;
  535. /** @return FrontendSpaApiKey[]|ArrayCollection|array */
  536. public function getFrontendSpaApiKeys(): Collection
  537. {
  538. return $this->frontendSpaApiKeys;
  539. }
  540. public function addFrontendSpaApiKey(FrontendSpaApiKey $newApiKey): void
  541. {
  542. foreach ($this->frontendSpaApiKeys as $apiKey) {
  543. if ($apiKey->getId() === $newApiKey->getId()) {
  544. throw new InvalidArgumentException("A frontend spa api key with id '{$apiKey->getId()}' is already attached to this user.");
  545. }
  546. }
  547. $this->frontendSpaApiKeys->add($newApiKey);
  548. }
  549. /**
  550. * @var DirectLoginAuthKey[]|ArrayCollection|array
  551. *
  552. * @ORM\OneToMany(targetEntity="App\Entity\DirectLoginAuthKey", mappedBy="user", cascade={"persist", "remove"}, fetch="EXTRA_LAZY")
  553. */
  554. protected $directLoginAuthKeys;
  555. /** @return DirectLoginAuthKey[]|ArrayCollection|array */
  556. public function getDirectLoginAuthKeys(): Collection
  557. {
  558. return $this->directLoginAuthKeys;
  559. }
  560. public function addDirectLoginAuthKey(DirectLoginAuthKey $newAuthKey): void
  561. {
  562. foreach ($this->directLoginAuthKeys as $authKey) {
  563. if ($authKey->getId() === $newAuthKey->getId()) {
  564. throw new InvalidArgumentException("A mobile direct login auth key with id '{$authKey->getId()}' is already attached to this user.");
  565. }
  566. }
  567. $this->directLoginAuthKeys->add($newAuthKey);
  568. }
  569. /**
  570. * @var EmailDeliveryNotification[]|ArrayCollection|array
  571. *
  572. * @ORM\OneToMany(targetEntity="App\Entity\EmailDeliveryNotification", mappedBy="user", cascade={"persist", "remove"}, fetch="EXTRA_LAZY")
  573. */
  574. protected $emailDeliveryNotifications;
  575. /**
  576. * @return EmailDeliveryNotification[]|array|ArrayCollection
  577. */
  578. public function getEmailDeliveryNotifications()
  579. {
  580. return $this->emailDeliveryNotifications;
  581. }
  582. /**
  583. * @param EmailDeliveryNotification[]|array|ArrayCollection $emailDeliveryNotifications
  584. */
  585. public function setEmailDeliveryNotifications($emailDeliveryNotifications): void
  586. {
  587. $this->emailDeliveryNotifications = $emailDeliveryNotifications;
  588. }
  589. // This allows registration using only email
  590. public function setEmail($email)
  591. {
  592. if (!is_null($email) && $email !== '' && !MailService::emailAddressIsValidForMailer($email)) {
  593. throw new InvalidEmailException("E-mail {$email} is not valid for SwiftMailer.");
  594. }
  595. $email = is_null($email) ? '' : $email;
  596. parent::setEmail($email);
  597. $this->setUsername($email);
  598. return $this;
  599. }
  600. public function hasAtLeastOneAdminRole(): bool
  601. {
  602. if ($this->hasRole(self::ROLE_NAME_ADMIN)
  603. || $this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  604. || $this->hasRole(self::ROLE_NAME_ADMIN_PROFILEVERIFIER)
  605. || $this->hasRole(self::ROLE_NAME_ADMIN_USER_CREATOR)
  606. || $this->hasRole(self::ROLE_NAME_ADMIN_CONTENT_DISTRIBUTION)
  607. || $this->hasRole(self::ROLE_NAME_ADMIN_BLACKLISTING)
  608. ) {
  609. return true;
  610. } else {
  611. return false;
  612. }
  613. }
  614. public function isNavigator(): bool
  615. {
  616. return $this->hasRole(self::ROLE_NAME_NAVIGATOR);
  617. }
  618. public function isIntegratedExternalPartnerManager(): bool
  619. {
  620. return $this->hasRole(self::ROLE_NAME_INTEGRATED_EXTERNAL_PARTNER_MANAGER);
  621. }
  622. public function isAllowedToUseFlaggedFeatures(): bool
  623. {
  624. if ($this->hasAtLeastOneAdminRole() || $this->hasRole(self::ROLE_NAME_EXTERNAL_FEATURE_TESTER)) {
  625. return true;
  626. } else {
  627. return false;
  628. }
  629. }
  630. public function isAllowedToRemoveUsers(): bool
  631. {
  632. if ($this->hasRole(self::ROLE_NAME_ADMIN)) {
  633. return true;
  634. } else {
  635. return false;
  636. }
  637. }
  638. public function isAllowedToModifyUsers(): bool
  639. {
  640. if ($this->hasRole(self::ROLE_NAME_ADMIN)) {
  641. return true;
  642. } else {
  643. return false;
  644. }
  645. }
  646. public function isAllowedToEditClearings(): bool
  647. {
  648. if ($this->hasRole(self::ROLE_NAME_ADMIN)) {
  649. return true;
  650. } else {
  651. return false;
  652. }
  653. }
  654. public function isAllowedToEditFAQs(): bool
  655. {
  656. if ($this->hasRole(self::ROLE_NAME_ADMIN)) {
  657. return true;
  658. } else {
  659. return false;
  660. }
  661. }
  662. public function isAllowedToReadRecurrentJobsOverviewData(): bool
  663. {
  664. if ($this->hasRole(self::ROLE_NAME_ADMIN)
  665. || $this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  666. ) {
  667. return true;
  668. } else {
  669. return false;
  670. }
  671. }
  672. public function isAllowedToModifyRecurrentJobs(): bool
  673. {
  674. if ($this->hasRole(self::ROLE_NAME_ADMIN)
  675. || $this->hasRole(self::ROLE_NAME_RECURRENT_JOBS_MANAGER)
  676. ) {
  677. return true;
  678. } else {
  679. return false;
  680. }
  681. }
  682. public function isAllowedToLogIntoUsers(): bool
  683. {
  684. if ($this->hasRole(self::ROLE_NAME_ADMIN)
  685. || $this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  686. ) {
  687. return true;
  688. } else {
  689. return false;
  690. }
  691. }
  692. public function isAllowedToReadContentDistributionData(): bool
  693. {
  694. return $this->isAllowedToModifyContentDistributionData();
  695. }
  696. public function isAllowedToModifyContentDistributionData(): bool
  697. {
  698. if ($this->hasRole(self::ROLE_NAME_ADMIN_CONTENT_DISTRIBUTION)
  699. ) {
  700. return true;
  701. } else {
  702. return false;
  703. }
  704. }
  705. public function isAllowedToModifyBlacklistingData(): bool
  706. {
  707. if ($this->hasRole(self::ROLE_NAME_ADMIN_BLACKLISTING)
  708. ) {
  709. return true;
  710. } else {
  711. return false;
  712. }
  713. }
  714. public function isAllowedToCreateUsers(): bool
  715. {
  716. if ($this->hasRole(self::ROLE_NAME_ADMIN_USER_CREATOR)
  717. ) {
  718. return true;
  719. } else {
  720. return false;
  721. }
  722. }
  723. public function isAllowedToModifyAgenturFuerArbeitData(): bool
  724. {
  725. if ($this->hasRole(self::ROLE_NAME_ADMIN)
  726. || $this->hasRole(self::ROLE_NAME_AGENTUR_FUER_ARBEIT_MANAGER)
  727. ) {
  728. return true;
  729. } else {
  730. return false;
  731. }
  732. }
  733. public function isAllowedToViewExternalPartnerCustomerReporting(): bool
  734. {
  735. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  736. || $this->hasRole(self::ROLE_NAME_ADMIN)
  737. || (
  738. $this->hasRole(self::ROLE_NAME_CUSTOMER_SPECIFIC_EXTERNAL_PARTNER_EVENT_AGGREGATIONS_READER)
  739. && $this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_READER)
  740. && $this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_GAUGES_READER)
  741. )
  742. ) {
  743. return true;
  744. }
  745. return false;
  746. }
  747. public function isAllowedToReadExternalPartnerEventAggregationsOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  748. {
  749. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  750. || $this->hasRole(self::ROLE_NAME_ADMIN)
  751. ) {
  752. return true;
  753. }
  754. if ($this->hasRole(self::ROLE_NAME_CUSTOMER_SPECIFIC_EXTERNAL_PARTNER_EVENT_AGGREGATIONS_READER)) {
  755. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  756. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  757. ) {
  758. return true;
  759. }
  760. }
  761. return false;
  762. }
  763. public function isAllowedToReadCampaignsOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  764. {
  765. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  766. || $this->hasRole(self::ROLE_NAME_ADMIN)
  767. ) {
  768. return true;
  769. }
  770. if ($this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_READER)) {
  771. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  772. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  773. ) {
  774. return true;
  775. }
  776. }
  777. return false;
  778. }
  779. public function isAllowedToWriteCampaignsOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  780. {
  781. if ($this->hasRole(self::ROLE_NAME_ADMIN)) {
  782. return true;
  783. }
  784. if ($this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_WRITER)) {
  785. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  786. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  787. ) {
  788. return true;
  789. }
  790. }
  791. return false;
  792. }
  793. public function isAllowedToReadGaugesOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  794. {
  795. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  796. || $this->hasRole(self::ROLE_NAME_ADMIN)
  797. ) {
  798. return true;
  799. }
  800. if ($this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_GAUGES_READER)) {
  801. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  802. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  803. ) {
  804. return true;
  805. }
  806. }
  807. return false;
  808. }
  809. public function isJobseeker(): bool
  810. {
  811. if ($this->hasRole(self::ROLE_NAME_JOBSEEKER)) {
  812. return true;
  813. } else {
  814. return false;
  815. }
  816. }
  817. public function isJobofferer(): bool
  818. {
  819. if ($this->hasRole(self::ROLE_NAME_JOBOFFERER)) {
  820. return true;
  821. } else {
  822. return false;
  823. }
  824. }
  825. public function isQuasiExternalPartner(): bool
  826. {
  827. if ($this->hasRole(self::ROLE_NAME_QUASI_EXTERNAL_PARTNER)) {
  828. return true;
  829. } else {
  830. return false;
  831. }
  832. }
  833. public function hasJobseekerProfile(): bool
  834. {
  835. if ($this->jobseekerProfiles->count() === 0) {
  836. return false;
  837. } else {
  838. return true;
  839. }
  840. }
  841. public function hasJoboffererProfile(): bool
  842. {
  843. if ($this->joboffererProfiles->count() === 0) {
  844. return false;
  845. } else {
  846. return true;
  847. }
  848. }
  849. public function hasAtLeastBasePlusProfile(): bool
  850. {
  851. if ($this->isJobofferer() && $this->hasJoboffererProfile()) {
  852. $profile = $this->getDefaultJoboffererProfile();
  853. if (!is_null($profile)) {
  854. return $profile->isBasePlusProfile();
  855. }
  856. }
  857. if ($this->isJobseeker() && $this->hasJobseekerProfile()) {
  858. $profile = $this->getDefaultJobseekerProfile();
  859. if (!is_null($profile)) {
  860. return $profile->isBasePlusProfile();
  861. }
  862. }
  863. return false;
  864. }
  865. /**
  866. * @ORM\Column(name="accepted_terms_and_conditions", type="boolean", nullable=false)
  867. */
  868. protected bool $acceptedTermsAndConditions = false;
  869. public function setAcceptedTermsAndConditions(bool $termsAndConditions): void
  870. {
  871. $this->acceptedTermsAndConditions = $termsAndConditions;
  872. }
  873. public function hasAcceptedTermsAndConditions(): bool
  874. {
  875. return $this->acceptedTermsAndConditions;
  876. }
  877. public function hasExtendedDefaultProfile(): bool
  878. {
  879. if ($this->isJobofferer() && $this->hasJoboffererProfile()) {
  880. $profile = $this->getDefaultJoboffererProfile();
  881. if (!is_null($profile)) {
  882. return $profile->isExtendedProfile();
  883. }
  884. }
  885. if ($this->isJobseeker() && $this->hasJobseekerProfile()) {
  886. $profile = $this->getDefaultJobseekerProfile();
  887. if (!is_null($profile)) {
  888. return $profile->isExtendedProfile();
  889. }
  890. }
  891. return false;
  892. }
  893. /**
  894. * @throws Exception
  895. */
  896. public function getDefaultJobseekerProfile(): ?JobseekerProfile
  897. {
  898. if (!$this->hasJobseekerProfile()) {
  899. return null;
  900. } else {
  901. $profiles = $this->getJobseekerProfiles();
  902. /** @var JobseekerProfile $profile */
  903. foreach ($profiles as $profile) {
  904. if ($profile->isDefault() === true) {
  905. return $profile;
  906. }
  907. }
  908. }
  909. throw new Exception('None of user ' . $this->getId() . ' job seeker profiles is marked as default!');
  910. }
  911. /**
  912. * @throws Exception
  913. */
  914. public function getDefaultJoboffererProfile(): ?JoboffererProfile
  915. {
  916. if (!$this->hasJoboffererProfile()) {
  917. return null;
  918. } else {
  919. $profiles = $this->getJoboffererProfiles();
  920. /** @var JoboffererProfile $profile */
  921. foreach ($profiles as $profile) {
  922. if ($profile->isDefault() === true) {
  923. return $profile;
  924. }
  925. }
  926. }
  927. throw new Exception('None of user ' . $this->getId() . ' job offerer profiles is marked as default!');
  928. }
  929. /**
  930. * @throws Exception
  931. */
  932. public function getDefaultProfile(): ?Profile
  933. {
  934. if ($this->isJobofferer()) {
  935. return $this->getDefaultJoboffererProfile();
  936. }
  937. if ($this->isJobseeker()) {
  938. return $this->getDefaultJobseekerProfile();
  939. }
  940. throw new Exception('User ' . $this->getId() . ' is neither jobofferer nor jobseeker!');
  941. }
  942. public function hasPhoto(): bool
  943. {
  944. if ($this->isJobofferer()) {
  945. return $this->getDefaultJoboffererProfile()->hasPhoto();
  946. }
  947. if ($this->isJobseeker()) {
  948. return $this->getDefaultJobseekerProfile()->hasPhoto();
  949. }
  950. return false;
  951. }
  952. public function getPhotoFileName(): string
  953. {
  954. if ($this->isJobofferer()) {
  955. return $this->getDefaultJoboffererProfile()->getPhotoFileName();
  956. }
  957. if ($this->isJobseeker()) {
  958. return $this->getDefaultJobseekerProfile()->getPhotoFileName();
  959. }
  960. return '';
  961. }
  962. public function isPaused(): bool
  963. {
  964. return ($this->isJobseeker() && $this->hasJobseekerProfile() && $this->getDefaultJobseekerProfile()->isPaused())
  965. || ($this->isJobofferer() && $this->hasJoboffererProfile() && $this->getDefaultJoboffererProfile()->isPaused());
  966. }
  967. /**
  968. * @var UserAdditionalInfo|Collection
  969. *
  970. * @ORM\OneToMany(targetEntity="App\Entity\ExternalPartner\UserAdditionalInfo", mappedBy="user", cascade={"persist", "remove"})
  971. */
  972. protected $externalPartnerUserAdditionalInfos;
  973. public function getExternalPartnerUserAdditionalInfoStringValueByName(string $infoName): ?string
  974. {
  975. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  976. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  977. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  978. return $externalPartnerUserAdditionalInfo->getInfoStringValue();
  979. }
  980. }
  981. return null;
  982. }
  983. /** @throws Exception */
  984. public function setExternalPartnerUserAdditionalInfoStringValueByName(string $infoName, string $stringValue): void
  985. {
  986. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  987. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  988. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  989. $externalPartnerUserAdditionalInfo->setInfoStringValue($stringValue);
  990. return;
  991. }
  992. }
  993. $externalPartnerUserAdditionalInfo = new UserAdditionalInfo();
  994. $externalPartnerUserAdditionalInfo->setUser($this);
  995. $externalPartnerUserAdditionalInfo->setInfoName($infoName);
  996. $externalPartnerUserAdditionalInfo->setInfoStringValue($stringValue);
  997. $this->externalPartnerUserAdditionalInfos->add($externalPartnerUserAdditionalInfo);
  998. }
  999. public function getExternalPartnerUserAdditionalInfoIntValueByName(string $infoName): ?int
  1000. {
  1001. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  1002. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  1003. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  1004. return $externalPartnerUserAdditionalInfo->getInfoIntValue();
  1005. }
  1006. }
  1007. return null;
  1008. }
  1009. /** @throws Exception */
  1010. public function setExternalPartnerUserAdditionalInfoIntValueByName(string $infoName, int $intValue): void
  1011. {
  1012. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  1013. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  1014. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  1015. $externalPartnerUserAdditionalInfo->setInfoIntValue($intValue);
  1016. return;
  1017. }
  1018. }
  1019. $externalPartnerUserAdditionalInfo = new UserAdditionalInfo();
  1020. $externalPartnerUserAdditionalInfo->setUser($this);
  1021. $externalPartnerUserAdditionalInfo->setInfoName($infoName);
  1022. $externalPartnerUserAdditionalInfo->setInfoIntValue($intValue);
  1023. $this->externalPartnerUserAdditionalInfos->add($externalPartnerUserAdditionalInfo);
  1024. }
  1025. /**
  1026. * @var \App\Entity\UserAdditionalInfo|Collection
  1027. *
  1028. * @ORM\OneToMany(targetEntity="App\Entity\UserAdditionalInfo", mappedBy="user", cascade={"persist", "remove"})
  1029. */
  1030. protected $userAdditionalInfos;
  1031. public function getUserAdditionalInfos(): Collection
  1032. {
  1033. return $this->userAdditionalInfos;
  1034. }
  1035. public function getUserAdditionalInfoStringValueByName(string $infoName): ?string
  1036. {
  1037. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1038. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1039. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1040. return $userAdditionalInfo->getInfoStringValue();
  1041. }
  1042. }
  1043. return null;
  1044. }
  1045. /** @throws Exception */
  1046. public function setUserAdditionalInfoStringValueByName(string $infoName, string $stringValue): void
  1047. {
  1048. if (!empty($this->userAdditionalInfos)) {
  1049. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1050. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1051. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1052. $userAdditionalInfo->setInfoStringValue($stringValue);
  1053. return;
  1054. }
  1055. }
  1056. }
  1057. $userAdditionalInfo = new \App\Entity\UserAdditionalInfo();
  1058. $userAdditionalInfo->setUser($this);
  1059. $userAdditionalInfo->setInfoName($infoName);
  1060. $userAdditionalInfo->setInfoStringValue($stringValue);
  1061. $this->userAdditionalInfos->add($userAdditionalInfo);
  1062. }
  1063. public function getUserAdditionalInfoIntValueByName(string $infoName): ?int
  1064. {
  1065. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1066. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1067. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1068. return $userAdditionalInfo->getInfoIntValue();
  1069. }
  1070. }
  1071. return null;
  1072. }
  1073. /** @throws Exception */
  1074. public function setUserAdditionalInfoIntValueByName(string $infoName, int $intValue): void
  1075. {
  1076. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1077. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1078. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1079. $userAdditionalInfo->setInfoIntValue($intValue);
  1080. return;
  1081. }
  1082. }
  1083. $userAdditionalInfo = new \App\Entity\UserAdditionalInfo();
  1084. $userAdditionalInfo->setUser($this);
  1085. $userAdditionalInfo->setInfoName($infoName);
  1086. $userAdditionalInfo->setInfoIntValue($intValue);
  1087. $this->userAdditionalInfos->add($userAdditionalInfo);
  1088. }
  1089. /**
  1090. * @var RecurrentJobBooking[]|Collection
  1091. *
  1092. * @ORM\OneToMany(targetEntity="App\Entity\Membership\RecurrentJobBooking", mappedBy="user", cascade={"persist", "remove"})
  1093. */
  1094. private Collection $recurrentJobBookings;
  1095. public function getRecurrentJobBookings(): Collection
  1096. {
  1097. return $this->recurrentJobBookings;
  1098. }
  1099. public function addRecurrentJobBooking(RecurrentJobBooking $recurrentJobBooking): void
  1100. {
  1101. $this->recurrentJobBookings->add($recurrentJobBooking);
  1102. }
  1103. public function isLinkedToExternalPartner(): bool
  1104. {
  1105. return !is_null($this->externalPartner);
  1106. }
  1107. public function isLinkedToExternalPartnerWithId(int $externalPartnerId): bool
  1108. {
  1109. return !is_null($this->externalPartner) && $this->externalPartner->getId() === $externalPartnerId;
  1110. }
  1111. /** @throws Exception */
  1112. public function isOwnerOfProfile(Profile $profile): bool
  1113. {
  1114. return $this->getDefaultProfile()->getId() === $profile->getId();
  1115. }
  1116. public function mustNotReceiveMails(): bool
  1117. {
  1118. return $this->getCreatedVia() === self::CREATED_VIA_RECRUIT_DL_RECURRENT_JOB_LANDINGPAGE && !$this->enabled;
  1119. }
  1120. public function getUserIdentifier(): string
  1121. {
  1122. return (string)$this->getEmail();
  1123. }
  1124. public function isAccountNonLocked(): bool
  1125. {
  1126. return !$this->isLocked();
  1127. }
  1128. public function __toString(): string
  1129. {
  1130. return (string)$this->getUsername() . ' - userId=' . $this->getId();
  1131. }
  1132. /**
  1133. * @var FlexMembershipRecurrentJobSlot[]|Collection
  1134. *
  1135. * @ORM\OneToMany(targetEntity="JanusHercules\Membership\Domain\Entity\FlexMembershipRecurrentJobSlot", mappedBy="user", cascade={"persist", "remove"})
  1136. */
  1137. private Collection $recurrentJobSlots;
  1138. public function getRecurrentJobSlots(): Collection
  1139. {
  1140. return $this->recurrentJobSlots;
  1141. }
  1142. public function addRecurrentJobSlot(FlexMembershipRecurrentJobSlot $recurrentJobSlot): void
  1143. {
  1144. $this->recurrentJobBookings->add($recurrentJobSlot);
  1145. }
  1146. public function removeRecurrentJobSlot(FlexMembershipRecurrentJobSlot $recurrentJobSlotToRemove): void
  1147. {
  1148. foreach ($this->recurrentJobSlots as $key => $slot) {
  1149. if ($slot->getId() === $recurrentJobSlotToRemove->getId()) {
  1150. $this->recurrentJobSlots->remove($key);
  1151. }
  1152. }
  1153. }
  1154. }