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 isAllowedToManageSelfServiceCampaigns(): bool
  683. {
  684. return $this->hasRole(self::ROLE_NAME_SELF_SERVICE_CAMPAIGN_ADMIN);
  685. }
  686. public function isAllowedToLogIntoUsers(): bool
  687. {
  688. if ($this->hasRole(self::ROLE_NAME_ADMIN)
  689. || $this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  690. ) {
  691. return true;
  692. } else {
  693. return false;
  694. }
  695. }
  696. public function isAllowedToReadContentDistributionData(): bool
  697. {
  698. return $this->isAllowedToModifyContentDistributionData();
  699. }
  700. public function isAllowedToModifyContentDistributionData(): bool
  701. {
  702. if ($this->hasRole(self::ROLE_NAME_ADMIN_CONTENT_DISTRIBUTION)
  703. ) {
  704. return true;
  705. } else {
  706. return false;
  707. }
  708. }
  709. public function isAllowedToModifyBlacklistingData(): bool
  710. {
  711. if ($this->hasRole(self::ROLE_NAME_ADMIN_BLACKLISTING)
  712. ) {
  713. return true;
  714. } else {
  715. return false;
  716. }
  717. }
  718. public function isAllowedToCreateUsers(): bool
  719. {
  720. if ($this->hasRole(self::ROLE_NAME_ADMIN_USER_CREATOR)
  721. ) {
  722. return true;
  723. } else {
  724. return false;
  725. }
  726. }
  727. public function isAllowedToModifyAgenturFuerArbeitData(): bool
  728. {
  729. if ($this->hasRole(self::ROLE_NAME_ADMIN)
  730. || $this->hasRole(self::ROLE_NAME_AGENTUR_FUER_ARBEIT_MANAGER)
  731. ) {
  732. return true;
  733. } else {
  734. return false;
  735. }
  736. }
  737. public function isAllowedToViewExternalPartnerCustomerReporting(): bool
  738. {
  739. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  740. || $this->hasRole(self::ROLE_NAME_ADMIN)
  741. || (
  742. $this->hasRole(self::ROLE_NAME_CUSTOMER_SPECIFIC_EXTERNAL_PARTNER_EVENT_AGGREGATIONS_READER)
  743. && $this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_READER)
  744. && $this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_GAUGES_READER)
  745. )
  746. ) {
  747. return true;
  748. }
  749. return false;
  750. }
  751. public function isAllowedToReadExternalPartnerEventAggregationsOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  752. {
  753. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  754. || $this->hasRole(self::ROLE_NAME_ADMIN)
  755. ) {
  756. return true;
  757. }
  758. if ($this->hasRole(self::ROLE_NAME_CUSTOMER_SPECIFIC_EXTERNAL_PARTNER_EVENT_AGGREGATIONS_READER)) {
  759. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  760. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  761. ) {
  762. return true;
  763. }
  764. }
  765. return false;
  766. }
  767. public function isAllowedToReadCampaignsOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  768. {
  769. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  770. || $this->hasRole(self::ROLE_NAME_ADMIN)
  771. ) {
  772. return true;
  773. }
  774. if ($this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_READER)) {
  775. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  776. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  777. ) {
  778. return true;
  779. }
  780. }
  781. return false;
  782. }
  783. public function isAllowedToWriteCampaignsOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  784. {
  785. if ($this->hasRole(self::ROLE_NAME_ADMIN)) {
  786. return true;
  787. }
  788. if ($this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_CAMPAIGNS_WRITER)) {
  789. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  790. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  791. ) {
  792. return true;
  793. }
  794. }
  795. return false;
  796. }
  797. public function isAllowedToReadGaugesOfCustomer(IntegratedExternalPartnerCustomer $customer): bool
  798. {
  799. if ($this->hasRole(self::ROLE_NAME_ADMIN_READONLY)
  800. || $this->hasRole(self::ROLE_NAME_ADMIN)
  801. ) {
  802. return true;
  803. }
  804. if ($this->hasRole(self::ROLE_NAME_SPECIFIC_CUSTOMER_GAUGES_READER)) {
  805. if (!is_null($this->getIntegratedExternalPartnerCustomer())
  806. && $this->getIntegratedExternalPartnerCustomer()->getId() === $customer->getId()
  807. ) {
  808. return true;
  809. }
  810. }
  811. return false;
  812. }
  813. public function isJobseeker(): bool
  814. {
  815. if ($this->hasRole(self::ROLE_NAME_JOBSEEKER)) {
  816. return true;
  817. } else {
  818. return false;
  819. }
  820. }
  821. public function isJobofferer(): bool
  822. {
  823. if ($this->hasRole(self::ROLE_NAME_JOBOFFERER)) {
  824. return true;
  825. } else {
  826. return false;
  827. }
  828. }
  829. public function isQuasiExternalPartner(): bool
  830. {
  831. if ($this->hasRole(self::ROLE_NAME_QUASI_EXTERNAL_PARTNER)) {
  832. return true;
  833. } else {
  834. return false;
  835. }
  836. }
  837. public function hasJobseekerProfile(): bool
  838. {
  839. if ($this->jobseekerProfiles->count() === 0) {
  840. return false;
  841. } else {
  842. return true;
  843. }
  844. }
  845. public function hasJoboffererProfile(): bool
  846. {
  847. if ($this->joboffererProfiles->count() === 0) {
  848. return false;
  849. } else {
  850. return true;
  851. }
  852. }
  853. public function hasAtLeastBasePlusProfile(): bool
  854. {
  855. if ($this->isJobofferer() && $this->hasJoboffererProfile()) {
  856. $profile = $this->getDefaultJoboffererProfile();
  857. if (!is_null($profile)) {
  858. return $profile->isBasePlusProfile();
  859. }
  860. }
  861. if ($this->isJobseeker() && $this->hasJobseekerProfile()) {
  862. $profile = $this->getDefaultJobseekerProfile();
  863. if (!is_null($profile)) {
  864. return $profile->isBasePlusProfile();
  865. }
  866. }
  867. return false;
  868. }
  869. /**
  870. * @ORM\Column(name="accepted_terms_and_conditions", type="boolean", nullable=false)
  871. */
  872. protected bool $acceptedTermsAndConditions = false;
  873. public function setAcceptedTermsAndConditions(bool $termsAndConditions): void
  874. {
  875. $this->acceptedTermsAndConditions = $termsAndConditions;
  876. }
  877. public function hasAcceptedTermsAndConditions(): bool
  878. {
  879. return $this->acceptedTermsAndConditions;
  880. }
  881. public function hasExtendedDefaultProfile(): bool
  882. {
  883. if ($this->isJobofferer() && $this->hasJoboffererProfile()) {
  884. $profile = $this->getDefaultJoboffererProfile();
  885. if (!is_null($profile)) {
  886. return $profile->isExtendedProfile();
  887. }
  888. }
  889. if ($this->isJobseeker() && $this->hasJobseekerProfile()) {
  890. $profile = $this->getDefaultJobseekerProfile();
  891. if (!is_null($profile)) {
  892. return $profile->isExtendedProfile();
  893. }
  894. }
  895. return false;
  896. }
  897. /**
  898. * @throws Exception
  899. */
  900. public function getDefaultJobseekerProfile(): ?JobseekerProfile
  901. {
  902. if (!$this->hasJobseekerProfile()) {
  903. return null;
  904. } else {
  905. $profiles = $this->getJobseekerProfiles();
  906. /** @var JobseekerProfile $profile */
  907. foreach ($profiles as $profile) {
  908. if ($profile->isDefault() === true) {
  909. return $profile;
  910. }
  911. }
  912. }
  913. throw new Exception('None of user ' . $this->getId() . ' job seeker profiles is marked as default!');
  914. }
  915. /**
  916. * @throws Exception
  917. */
  918. public function getDefaultJoboffererProfile(): ?JoboffererProfile
  919. {
  920. if (!$this->hasJoboffererProfile()) {
  921. return null;
  922. } else {
  923. $profiles = $this->getJoboffererProfiles();
  924. /** @var JoboffererProfile $profile */
  925. foreach ($profiles as $profile) {
  926. if ($profile->isDefault() === true) {
  927. return $profile;
  928. }
  929. }
  930. }
  931. throw new Exception('None of user ' . $this->getId() . ' job offerer profiles is marked as default!');
  932. }
  933. /**
  934. * @throws Exception
  935. */
  936. public function getDefaultProfile(): ?Profile
  937. {
  938. if ($this->isJobofferer()) {
  939. return $this->getDefaultJoboffererProfile();
  940. }
  941. if ($this->isJobseeker()) {
  942. return $this->getDefaultJobseekerProfile();
  943. }
  944. throw new Exception('User ' . $this->getId() . ' is neither jobofferer nor jobseeker!');
  945. }
  946. public function hasPhoto(): bool
  947. {
  948. if ($this->isJobofferer()) {
  949. return $this->getDefaultJoboffererProfile()->hasPhoto();
  950. }
  951. if ($this->isJobseeker()) {
  952. return $this->getDefaultJobseekerProfile()->hasPhoto();
  953. }
  954. return false;
  955. }
  956. public function getPhotoFileName(): string
  957. {
  958. if ($this->isJobofferer()) {
  959. return $this->getDefaultJoboffererProfile()->getPhotoFileName();
  960. }
  961. if ($this->isJobseeker()) {
  962. return $this->getDefaultJobseekerProfile()->getPhotoFileName();
  963. }
  964. return '';
  965. }
  966. public function isPaused(): bool
  967. {
  968. return ($this->isJobseeker() && $this->hasJobseekerProfile() && $this->getDefaultJobseekerProfile()->isPaused())
  969. || ($this->isJobofferer() && $this->hasJoboffererProfile() && $this->getDefaultJoboffererProfile()->isPaused());
  970. }
  971. /**
  972. * @var UserAdditionalInfo|Collection
  973. *
  974. * @ORM\OneToMany(targetEntity="App\Entity\ExternalPartner\UserAdditionalInfo", mappedBy="user", cascade={"persist", "remove"})
  975. */
  976. protected $externalPartnerUserAdditionalInfos;
  977. public function getExternalPartnerUserAdditionalInfoStringValueByName(string $infoName): ?string
  978. {
  979. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  980. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  981. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  982. return $externalPartnerUserAdditionalInfo->getInfoStringValue();
  983. }
  984. }
  985. return null;
  986. }
  987. /** @throws Exception */
  988. public function setExternalPartnerUserAdditionalInfoStringValueByName(string $infoName, string $stringValue): void
  989. {
  990. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  991. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  992. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  993. $externalPartnerUserAdditionalInfo->setInfoStringValue($stringValue);
  994. return;
  995. }
  996. }
  997. $externalPartnerUserAdditionalInfo = new UserAdditionalInfo();
  998. $externalPartnerUserAdditionalInfo->setUser($this);
  999. $externalPartnerUserAdditionalInfo->setInfoName($infoName);
  1000. $externalPartnerUserAdditionalInfo->setInfoStringValue($stringValue);
  1001. $this->externalPartnerUserAdditionalInfos->add($externalPartnerUserAdditionalInfo);
  1002. }
  1003. public function getExternalPartnerUserAdditionalInfoIntValueByName(string $infoName): ?int
  1004. {
  1005. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  1006. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  1007. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  1008. return $externalPartnerUserAdditionalInfo->getInfoIntValue();
  1009. }
  1010. }
  1011. return null;
  1012. }
  1013. /** @throws Exception */
  1014. public function setExternalPartnerUserAdditionalInfoIntValueByName(string $infoName, int $intValue): void
  1015. {
  1016. /** @var UserAdditionalInfo $externalPartnerUserAdditionalInfo */
  1017. foreach ($this->externalPartnerUserAdditionalInfos as $externalPartnerUserAdditionalInfo) {
  1018. if ($externalPartnerUserAdditionalInfo->getInfoName() === $infoName) {
  1019. $externalPartnerUserAdditionalInfo->setInfoIntValue($intValue);
  1020. return;
  1021. }
  1022. }
  1023. $externalPartnerUserAdditionalInfo = new UserAdditionalInfo();
  1024. $externalPartnerUserAdditionalInfo->setUser($this);
  1025. $externalPartnerUserAdditionalInfo->setInfoName($infoName);
  1026. $externalPartnerUserAdditionalInfo->setInfoIntValue($intValue);
  1027. $this->externalPartnerUserAdditionalInfos->add($externalPartnerUserAdditionalInfo);
  1028. }
  1029. /**
  1030. * @var \App\Entity\UserAdditionalInfo|Collection
  1031. *
  1032. * @ORM\OneToMany(targetEntity="App\Entity\UserAdditionalInfo", mappedBy="user", cascade={"persist", "remove"})
  1033. */
  1034. protected $userAdditionalInfos;
  1035. public function getUserAdditionalInfos(): Collection
  1036. {
  1037. return $this->userAdditionalInfos;
  1038. }
  1039. public function getUserAdditionalInfoStringValueByName(string $infoName): ?string
  1040. {
  1041. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1042. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1043. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1044. return $userAdditionalInfo->getInfoStringValue();
  1045. }
  1046. }
  1047. return null;
  1048. }
  1049. /** @throws Exception */
  1050. public function setUserAdditionalInfoStringValueByName(string $infoName, string $stringValue): void
  1051. {
  1052. if (!empty($this->userAdditionalInfos)) {
  1053. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1054. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1055. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1056. $userAdditionalInfo->setInfoStringValue($stringValue);
  1057. return;
  1058. }
  1059. }
  1060. }
  1061. $userAdditionalInfo = new \App\Entity\UserAdditionalInfo();
  1062. $userAdditionalInfo->setUser($this);
  1063. $userAdditionalInfo->setInfoName($infoName);
  1064. $userAdditionalInfo->setInfoStringValue($stringValue);
  1065. $this->userAdditionalInfos->add($userAdditionalInfo);
  1066. }
  1067. public function getUserAdditionalInfoIntValueByName(string $infoName): ?int
  1068. {
  1069. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1070. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1071. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1072. return $userAdditionalInfo->getInfoIntValue();
  1073. }
  1074. }
  1075. return null;
  1076. }
  1077. /** @throws Exception */
  1078. public function setUserAdditionalInfoIntValueByName(string $infoName, int $intValue): void
  1079. {
  1080. /** @var \App\Entity\UserAdditionalInfo $userAdditionalInfo */
  1081. foreach ($this->userAdditionalInfos as $userAdditionalInfo) {
  1082. if ($userAdditionalInfo->getInfoName() === $infoName) {
  1083. $userAdditionalInfo->setInfoIntValue($intValue);
  1084. return;
  1085. }
  1086. }
  1087. $userAdditionalInfo = new \App\Entity\UserAdditionalInfo();
  1088. $userAdditionalInfo->setUser($this);
  1089. $userAdditionalInfo->setInfoName($infoName);
  1090. $userAdditionalInfo->setInfoIntValue($intValue);
  1091. $this->userAdditionalInfos->add($userAdditionalInfo);
  1092. }
  1093. /**
  1094. * @var RecurrentJobBooking[]|Collection
  1095. *
  1096. * @ORM\OneToMany(targetEntity="App\Entity\Membership\RecurrentJobBooking", mappedBy="user", cascade={"persist", "remove"})
  1097. */
  1098. private Collection $recurrentJobBookings;
  1099. public function getRecurrentJobBookings(): Collection
  1100. {
  1101. return $this->recurrentJobBookings;
  1102. }
  1103. public function addRecurrentJobBooking(RecurrentJobBooking $recurrentJobBooking): void
  1104. {
  1105. $this->recurrentJobBookings->add($recurrentJobBooking);
  1106. }
  1107. public function isLinkedToExternalPartner(): bool
  1108. {
  1109. return !is_null($this->externalPartner);
  1110. }
  1111. public function isLinkedToExternalPartnerWithId(int $externalPartnerId): bool
  1112. {
  1113. return !is_null($this->externalPartner) && $this->externalPartner->getId() === $externalPartnerId;
  1114. }
  1115. /** @throws Exception */
  1116. public function isOwnerOfProfile(Profile $profile): bool
  1117. {
  1118. return $this->getDefaultProfile()->getId() === $profile->getId();
  1119. }
  1120. public function mustNotReceiveMails(): bool
  1121. {
  1122. return $this->getCreatedVia() === self::CREATED_VIA_RECRUIT_DL_RECURRENT_JOB_LANDINGPAGE && !$this->enabled;
  1123. }
  1124. public function getUserIdentifier(): string
  1125. {
  1126. return (string)$this->getEmail();
  1127. }
  1128. public function isAccountNonLocked(): bool
  1129. {
  1130. return !$this->isLocked();
  1131. }
  1132. public function __toString(): string
  1133. {
  1134. return (string)$this->getUsername() . ' - userId=' . $this->getId();
  1135. }
  1136. /**
  1137. * @var FlexMembershipRecurrentJobSlot[]|Collection
  1138. *
  1139. * @ORM\OneToMany(targetEntity="JanusHercules\Membership\Domain\Entity\FlexMembershipRecurrentJobSlot", mappedBy="user", cascade={"persist", "remove"})
  1140. */
  1141. private Collection $recurrentJobSlots;
  1142. public function getRecurrentJobSlots(): Collection
  1143. {
  1144. return $this->recurrentJobSlots;
  1145. }
  1146. public function addRecurrentJobSlot(FlexMembershipRecurrentJobSlot $recurrentJobSlot): void
  1147. {
  1148. $this->recurrentJobBookings->add($recurrentJobSlot);
  1149. }
  1150. public function removeRecurrentJobSlot(FlexMembershipRecurrentJobSlot $recurrentJobSlotToRemove): void
  1151. {
  1152. foreach ($this->recurrentJobSlots as $key => $slot) {
  1153. if ($slot->getId() === $recurrentJobSlotToRemove->getId()) {
  1154. $this->recurrentJobSlots->remove($key);
  1155. }
  1156. }
  1157. }
  1158. }