<?php
namespace App\Entity\Profile;
use App\Entity\ContentDistribution\AgenturFuerArbeit\DestatisEconomicSector;
use App\Entity\ConversationMessage\ConversationMessage;
use App\Entity\EconomicSector;
use App\Entity\ExternalPartner\JoboffererProfileAdditionalInfo;
use App\Entity\JoboffererProfileAdditionalFile;
use App\Entity\Profile;
use App\Entity\ProfileBlock;
use App\Entity\ProfileFavorization;
use App\Entity\ProfileReview;
use App\Entity\RecurrentJob;
use App\Entity\User;
use App\Exception\InvalidEmailException;
use App\Service\DestatisEconomicSectorService;
use App\Service\MailService;
use App\Service\XmlFormattingService;
use App\Utility\ReflectionHelper;
use App\Utility\TextCleaner;
use App\Validator\Constraint as AppAssert;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Exception;
use InvalidArgumentException;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* @ORM\Entity
*
* @ORM\Table(name="jobofferer_profiles")
*/
class JoboffererProfile extends Profile
{
public const LIMITED_IN_SEARCH_VALUE_FALSE = 0;
public const LIMITED_IN_SEARCH_VALUE_TRUE = 1;
public const LIMITED_IN_SEARCH_VALUE_FALSE_BY_HAND = 2;
public const LIMITED_IN_SEARCH_VALUE_TRUE_BY_HAND = 3;
public function __construct()
{
parent::__construct();
$this->recurrentJobs = new ArrayCollection();
$this->additionalFiles = new ArrayCollection();
$this->selfdescription = '';
$this->identifiedAsRecruitmentAgency = false;
$this->limitedInSearch = self::LIMITED_IN_SEARCH_VALUE_TRUE;
}
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="joboffererProfiles", cascade={"persist"})
*
* @ORM\JoinColumn(name="users_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $user;
/**
* @ORM\Column(name="selfdescription", type="text", length=10000, nullable=true)
*
* @Assert\Type("string")
*/
protected ?string $selfdescription;
public function setSelfdescription(
?string $selfdescription = null,
?bool $formatHeadings = true
): void {
if ($formatHeadings) {
// Headings that are greater than h4 should not exist in the description text and should be replaced with h4 headings
$selfdescription = XmlFormattingService::formatHeadingsForDescriptionTexts($selfdescription);
}
$this->selfdescription = $selfdescription;
}
public function getSelfdescription(): ?string
{
return TextCleaner::removeSpecialCharacters($this->selfdescription);
}
/**
* @ORM\Column(name="firstname", type="string", length=128, nullable=true)
*
* @Assert\Type("string")
*
* @Assert\Length(
* min = 0,
* max = 50,
* )
*/
protected ?string $firstname;
public function setFirstname(?string $firstname = null): void
{
$this->firstname = $firstname;
}
public function getFirstname(): ?string
{
return $this->firstname;
}
/**
* @ORM\Column(name="lastname", type="string", length=128, nullable=true)
*
* @Assert\Type("string")
*
* @Assert\Length(
* min = 0,
* max = 50,
* )
*/
protected ?string $lastname;
public function setLastname(?string $lastname = null): void
{
$this->lastname = $lastname;
}
public function getLastname(): ?string
{
return $this->lastname;
}
/**
* @ORM\Column(name="address", type="string", length=128, nullable=true)
*
* @Assert\Type("string")
*
* @Assert\NotBlank()
*
* @Assert\Length(
* min = 5,
* max = 128,
* )
*/
protected ?string $address;
public function setAddress(?string $address = null): void
{
$this->address = $address;
}
public function getAddress(): ?string
{
return $this->address;
}
/**
* @ORM\Column(name="zipcode", type="string", length=128, nullable=true)
*
* @Assert\Type("string")
*
* @Assert\NotNull()
*
* @Assert\NotBlank()
*
* @AppAssert\KnownZipcode
*/
protected ?string $zipcode = null;
public function setZipcode(
?string $zipcode = null
): void {
if (!is_null($zipcode)) {
$trimmedZipcode = trim($zipcode);
if (mb_strlen($trimmedZipcode) !== 5 || !is_numeric($trimmedZipcode)) {
throw new InvalidArgumentException("zipcode must either be null or a string with 5 digits, but got '$zipcode'");
}
$zipcode = $trimmedZipcode;
}
$this->zipcode = $zipcode;
}
public function getZipcode(): ?string
{
return $this->zipcode;
}
/**
* @ORM\Column(name="city", type="string", length=128, nullable=true)
*
* @Assert\Type("string")
*
* @Assert\NotBlank()
*
* @Assert\Length(
* min = 2,
* max = 128,
* )
*/
protected ?string $city;
public function setCity(?string $city): void
{
$this->city = mb_substr($city, 0, 128);
}
public function getCity(): ?string
{
return $this->city;
}
/**
* @var ConversationMessage[]|Collection|array
*
* @ORM\OneToMany(targetEntity="\App\Entity\ConversationMessage\ConversationMessage", mappedBy="joboffererProfile", cascade={"persist", "remove"})
*/
protected array|Collection $conversationMessages;
public function addConversationMessage(ConversationMessage $conversationMessage): void
{
$this->conversationMessages[] = $conversationMessage;
}
public function getConversationMessages(): Collection
{
return $this->conversationMessages;
}
/**
* @var ProfileReview|Collection
*
* @ORM\OneToMany(targetEntity="\App\Entity\ProfileReview", mappedBy="joboffererProfile", cascade={"persist", "remove"})
*/
protected $profileReviews;
public function addProfileReview(ProfileReview $profileReview): void
{
$this->profileReviews[] = $profileReview;
}
public function getProfileReviews(): ProfileReview|Collection
{
return $this->profileReviews;
}
/**
* @var ProfileBlock|Collection
*
* @ORM\OneToMany(targetEntity="\App\Entity\ProfileBlock", mappedBy="joboffererProfile", cascade={"persist", "remove"})
*/
protected $profileBlocks;
public function addProfileBlock(ProfileBlock $profileBlock): void
{
$this->profileBlocks[] = $profileBlock;
}
public function getProfileBlocks(): Collection|ProfileBlock
{
return $this->profileBlocks;
}
public function getProfileBlockForBlockOfJobseekerProfile(JobseekerProfile $jobseekerProfile): ProfileBlock
{
/** @var ProfileBlock $profileBlock */
foreach ($this->profileBlocks as $profileBlock) {
if ($profileBlock->isBlocker($this) && $profileBlock->getJobseekerProfile()->getId() === $jobseekerProfile->getId()) {
return $profileBlock;
}
}
throw new Exception('Jobofferer profile ' . $this->getId() . ' has not blocked jobseeker profile ' . $jobseekerProfile->getId());
}
/**
* @var ProfileFavorization|Collection
*
* @ORM\OneToMany(targetEntity="\App\Entity\ProfileFavorization", mappedBy="joboffererProfile", cascade={"persist", "remove"})
*/
protected $profileFavorizations;
public function addProfileFavorization(ProfileFavorization $profileFavorization): void
{
$this->profileFavorizations[] = $profileFavorization;
}
public function getProfileFavorizations(): Collection|ProfileFavorization
{
return $this->profileFavorizations;
}
public function getProfileFavorizationForFavorizationOfJobseekerProfile(JobseekerProfile $jobseekerProfile): ProfileFavorization
{
/** @var ProfileFavorization $profileFavorization */
foreach ($this->profileFavorizations as $profileFavorization) {
if ($profileFavorization->isFavorer($this) && $profileFavorization->getJobseekerProfile()->getId() === $jobseekerProfile->getId()) {
return $profileFavorization;
}
}
throw new Exception('Jobofferer profile ' . $this->getId() . ' has not favored jobseeker profile ' . $jobseekerProfile->getId());
}
/**
* @var RecurrentJob[]|Collection
*
* @ORM\OneToMany(targetEntity="\App\Entity\RecurrentJob", mappedBy="joboffererProfile", cascade={"persist", "remove"})
*/
protected array|Collection|ArrayCollection $recurrentJobs;
public function addRecurrentJob(RecurrentJob $recurrentJobs): void
{
$this->recurrentJobs[] = $recurrentJobs;
}
public function removeRecurrentJob(RecurrentJob $recurrentJobToRemove): void
{
foreach ($this->recurrentJobs as $key => $recurrentJob) {
if ($recurrentJob->getId() === $recurrentJobToRemove->getId()) {
$this->recurrentJobs->remove($key);
}
}
}
/**
* @return RecurrentJob[]|Collection
*/
public function getRecurrentJobs(): array|ArrayCollection|Collection
{
return $this->recurrentJobs;
}
/**
* @var JoboffererProfileAdditionalFile|Collection
*
* @ORM\OneToMany(targetEntity="\App\Entity\JoboffererProfileAdditionalFile", mappedBy="joboffererProfile", cascade={"persist", "remove"})
*/
protected Collection|ArrayCollection|JoboffererProfileAdditionalFile $additionalFiles;
public function getAdditionalFiles(): JoboffererProfileAdditionalFile|ArrayCollection|Collection
{
return $this->additionalFiles;
}
/**
* @ORM\Column(name="businessName", type="string", length=128, nullable=true)
*
* @Assert\Type("string")
*
* @Assert\NotBlank()
*
* @Assert\Length(
* min = 2,
* max = 100,
* )
*/
protected ?string $businessName;
public function setBusinessName(?string $businessName = null): void
{
if (!is_null($businessName)) {
$this->businessName = mb_substr($businessName, 0, 128);
} else {
$this->businessName = null;
}
}
public function getBusinessName(): ?string
{
return $this->businessName;
}
/**
* @ORM\ManyToOne(targetEntity="App\Entity\EconomicSector", cascade={"persist"})
*
* @ORM\JoinColumn(name="economic_sectors_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
*/
protected ?EconomicSector $economicSector;
public function getEconomicSector(): ?EconomicSector
{
return $this->economicSector;
}
public function setEconomicSector(EconomicSector $economicSector): void
{
$this->economicSector = $economicSector;
}
/**
* @Assert\Callback
*/
public function validate(ExecutionContextInterface $context, $payload): void
{
parent::validate($context, $payload);
}
/**
* @ORM\Column(name="paused_since", type="datetime", nullable=true)
*
* @Assert\Type("datetime")
*/
private $pausedSince;
public function getPausedSince(): ?DateTime
{
return $this->pausedSince;
}
public function setPausedSince(?DateTime $pausedSince = null): void
{
$this->pausedSince = $pausedSince;
}
public function isPaused(): bool
{
return $this->pausedSince !== null;
}
public function getStarsScoreRating(): float
{
$score = 2.5;
$step = 0.5;
$score += $this->getSelfdescription() ? $step : 0;
$score += $this->getMobilenumber() ? $step : 0;
$score += $this->getPhotoFileName() ? $step : 0;
return $score;
}
/**
* @ORM\OneToMany(targetEntity="App\Entity\ExternalPartner\JoboffererProfileAdditionalInfo", mappedBy="joboffererProfile", cascade={"persist", "remove"})
*/
protected $externalPartnerJoboffererProfileAdditionalInfos;
public function getExternalPartnerJoboffererProfileAdditionalInfos(): array
{
$externalPartnerJoboffererProfileInfoArray = [];
/* @var JoboffererProfileAdditionalInfo $externalPartnerJoboffererProfileAdditionalInfo */
if (!is_null($this->externalPartnerJoboffererProfileAdditionalInfos)) {
foreach ($this->externalPartnerJoboffererProfileAdditionalInfos as $externalPartnerJoboffererProfileAdditionalInfo) {
$externalPartnerJoboffererProfileInfoArray[] = $externalPartnerJoboffererProfileAdditionalInfo;
}
}
return $externalPartnerJoboffererProfileInfoArray;
}
public function getExternalPartnerJoboffererProfileAdditionalInfoStringValueByName(string $infoName): ?string
{
/* @var JoboffererProfileAdditionalInfo $externalPartnerJoboffererProfileAdditionalInfo */
if (!is_null($this->externalPartnerJoboffererProfileAdditionalInfos)) {
foreach ($this->externalPartnerJoboffererProfileAdditionalInfos as $externalPartnerJoboffererProfileAdditionalInfo) {
if ($externalPartnerJoboffererProfileAdditionalInfo->getInfoName() === $infoName) {
return $externalPartnerJoboffererProfileAdditionalInfo->getInfoStringValue();
}
}
}
return null;
}
/** @throws Exception */
public function setExternalPartnerJoboffererProfileAdditionalInfoStringValueByName(string $infoName, ?string $stringValue): void
{
if (!is_null($this->externalPartnerJoboffererProfileAdditionalInfos)) {
/** @var JoboffererProfileAdditionalInfo $externalPartnerJoboffererProfileAdditionalInfo */
foreach ($this->externalPartnerJoboffererProfileAdditionalInfos as $externalPartnerJoboffererProfileAdditionalInfo) {
if ($externalPartnerJoboffererProfileAdditionalInfo->getInfoName() === $infoName) {
$externalPartnerJoboffererProfileAdditionalInfo->setInfoStringValue($stringValue);
return;
}
}
} else {
$this->externalPartnerJoboffererProfileAdditionalInfos = new ArrayCollection();
}
$externalPartnerJoboffererProfileAdditionalInfo = new JoboffererProfileAdditionalInfo();
$externalPartnerJoboffererProfileAdditionalInfo->setJoboffererProfile($this);
$externalPartnerJoboffererProfileAdditionalInfo->setInfoName($infoName);
$externalPartnerJoboffererProfileAdditionalInfo->setInfoStringValue($stringValue);
$this->externalPartnerJoboffererProfileAdditionalInfos->add($externalPartnerJoboffererProfileAdditionalInfo);
}
public function getExternalPartnerJoboffererProfileAdditionalInfoIntValueByName(string $infoName): ?int
{
if (!is_null($this->externalPartnerJoboffererProfileAdditionalInfos)) {
/** @var JoboffererProfileAdditionalInfo $externalPartnerJoboffererProfileAdditionalInfo */
foreach ($this->externalPartnerJoboffererProfileAdditionalInfos as $externalPartnerJoboffererProfileAdditionalInfo) {
if ($externalPartnerJoboffererProfileAdditionalInfo->getInfoName() === $infoName) {
return $externalPartnerJoboffererProfileAdditionalInfo->getInfoIntValue();
}
}
}
return null;
}
/** @throws Exception */
public function setExternalPartnerJoboffererProfileAdditionalInfoIntValueByName(string $infoName, int $intValue): void
{
if (!is_null($this->externalPartnerJoboffererProfileAdditionalInfos)) {
/** @var JoboffererProfileAdditionalInfo $externalPartnerJoboffererProfileAdditionalInfo */
foreach ($this->externalPartnerJoboffererProfileAdditionalInfos as $externalPartnerJoboffererProfileAdditionalInfo) {
if ($externalPartnerJoboffererProfileAdditionalInfo->getInfoName() === $infoName) {
$externalPartnerJoboffererProfileAdditionalInfo->setInfoIntValue($intValue);
return;
}
}
} else {
$this->externalPartnerJoboffererProfileAdditionalInfos = new ArrayCollection();
}
$externalPartnerJoboffererProfileAdditionalInfo = new JoboffererProfileAdditionalInfo();
$externalPartnerJoboffererProfileAdditionalInfo->setJoboffererProfile($this);
$externalPartnerJoboffererProfileAdditionalInfo->setInfoName($infoName);
$externalPartnerJoboffererProfileAdditionalInfo->setInfoIntValue($intValue);
$this->externalPartnerJoboffererProfileAdditionalInfos->add($externalPartnerJoboffererProfileAdditionalInfo);
}
/**
* @ORM\ManyToOne(targetEntity="App\Entity\ContentDistribution\AgenturFuerArbeit\DestatisEconomicSector", cascade={"persist"})
*
* @ORM\JoinColumn(name="destatis_economic_sectors_running_number", referencedColumnName="running_number", nullable=true, onDelete="SET NULL")
*/
protected ?DestatisEconomicSector $destatisEconomicSector = null;
public function getDestatisEconomicSector(): ?DestatisEconomicSector
{
if (is_null($this->destatisEconomicSector)
&& !is_null($this->getUser()->getIntegratedExternalPartnerCustomer())
) {
return $this
->getUser()
->getIntegratedExternalPartnerCustomer()
->getDestatisEconomicSector();
}
return $this->destatisEconomicSector;
}
public function setDestatisEconomicSector(?DestatisEconomicSector $destatisEconomicSector): void
{
$this->destatisEconomicSector = $destatisEconomicSector;
}
/**
* @ORM\Column(name="destatis_economic_sector_decision", type="smallint", nullable=true, options={"unsigned": true})
*/
protected ?int $destatisEconomicSectorDecision;
public function setDestatisEconomicSectorDecision(?int $destatisEconomicSectorDecision): void
{
if (!is_null($destatisEconomicSectorDecision)) {
if (!ReflectionHelper::hasConstWithValue(
DestatisEconomicSectorService::class,
'SECTOR_DECISION_',
$destatisEconomicSectorDecision)
) {
throw new InvalidArgumentException("Value '$destatisEconomicSectorDecision' not allowed for destatisEconomicSectorDecision.");
}
}
$this->destatisEconomicSectorDecision = $destatisEconomicSectorDecision;
}
public function getDestatisEconomicSectorDecision(): ?int
{
if (is_null($this->destatisEconomicSectorDecision)
&& !is_null($this->getUser()->getIntegratedExternalPartnerCustomer())
) {
return $this
->getUser()
->getIntegratedExternalPartnerCustomer()
->getDestatisEconomicSectorDecision();
}
return $this->destatisEconomicSectorDecision;
}
public function getDestatisEconomicSectorOrigin(): ?int
{
if (!is_null($this->destatisEconomicSector)) {
return DestatisEconomicSectorService::SECTOR_ORIGIN_JOBOFFERER_PROFILE;
}
if (!is_null($this->getUser()->getIntegratedExternalPartnerCustomer())) {
return $this
->getUser()
->getIntegratedExternalPartnerCustomer()
->getDestatisEconomicSectorOrigin();
}
return null;
}
/**
* @ORM\Column(name="identified_as_recruitment_agency", type="boolean", nullable=false)
*/
private bool $identifiedAsRecruitmentAgency;
public function isIdentifiedAsRecruitmentAgency(): bool
{
return $this->identifiedAsRecruitmentAgency;
}
// please consider using the method markAsRecruitmentAgency() instead of the direct setter
public function setIdentifiedAsRecruitmentAgency(bool $identifiedAsRecruitmentAgency): void
{
$this->identifiedAsRecruitmentAgency = $identifiedAsRecruitmentAgency;
}
/**
* @ORM\Column(name="limited_in_search", type="smallint", nullable=false)
*/
private int $limitedInSearch;
public function getLimitedInSearch(): int
{
return $this->limitedInSearch;
}
public function isLimitedInSearch(): int
{
return $this->limitedInSearch === self::LIMITED_IN_SEARCH_VALUE_TRUE || $this->limitedInSearch === self::LIMITED_IN_SEARCH_VALUE_TRUE_BY_HAND;
}
public function setLimitedInSearch(int $limitedInSearch): void
{
if (!ReflectionHelper::hasConstWithValue(
self::class,
'LIMITED_IN_SEARCH_VALUE_',
$limitedInSearch)
) {
throw new InvalidArgumentException("Value '$limitedInSearch' not allowed for limitedInSearch.");
}
$this->limitedInSearch = $limitedInSearch;
}
/**
* @ORM\Column(name="email_for_invoice", type="string", nullable=true)
*/
protected ?string $emailForInvoice;
public function setEmailForInvoice(
?string $emailForInvoice = null
): void {
if (!is_null($emailForInvoice) && $emailForInvoice !== '' && !MailService::emailAddressIsValidForMailer($emailForInvoice)) {
throw new InvalidEmailException("E-mail {$emailForInvoice} is not valid for SwiftMailer.");
}
$this->emailForInvoice = $emailForInvoice;
}
public function getEmailForInvoice(): ?string
{
return $this->emailForInvoice;
}
}