accompanyingPeriodParticipations = new ArrayCollection(); $this->spokenLanguages = new ArrayCollection(); $this->addresses = new ArrayCollection(); $this->altNames = new ArrayCollection(); $this->otherPhoneNumbers = new ArrayCollection(); if (null === $opening) { $opening = new DateTime(); } $this->open(new AccompanyingPeriod($opening)); } /** * @return string */ public function __toString() { return $this->getLabel(); } /** * Add AccompanyingPeriodParticipation. * * @uses AccompanyingPeriod::addPerson */ public function addAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): self { $participation = new AccompanyingPeriodParticipation($accompanyingPeriod, $this); $this->accompanyingPeriodParticipations->add($participation); return $this; } /** * @return $this */ public function addAddress(Address $address) { $this->addresses[] = $address; return $this; } /** * @return $this */ public function addAltName(PersonAltName $altName) { if (false === $this->altNames->contains($altName)) { $this->altNames->add($altName); $altName->setPerson($this); } return $this; } /** * @return $this */ public function addOtherPhoneNumber(PersonPhone $otherPhoneNumber) { if (false === $this->otherPhoneNumbers->contains($otherPhoneNumber)) { $otherPhoneNumber->setPerson($this); $this->otherPhoneNumbers->add($otherPhoneNumber); } return $this; } // a period opened and another one after it /** * Function used for validation that check if the accompanying periods of * the person are not collapsing (i.e. have not shared days) or having * a period after an open period. * * @return true | array True if the accompanying periods are not collapsing, * an array with data for displaying the error */ public function checkAccompanyingPeriodsAreNotCollapsing() { $periods = $this->getAccompanyingPeriodsOrdered(); $periodsNbr = count($periods); $i = 0; while ($periodsNbr - 1 > $i) { $periodI = $periods[$i]; $periodAfterI = $periods[$i + 1]; if ($periodI->isOpen()) { return [ 'result' => self::ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD, 'dateOpening' => $periodAfterI->getOpeningDate(), 'dateClosing' => $periodAfterI->getClosingDate(), 'date' => $periodI->getOpeningDate(), ]; } if ($periodI->getClosingDate() >= $periodAfterI->getOpeningDate()) { return [ 'result' => self::ERROR_PERIODS_ARE_COLLAPSING, 'dateOpening' => $periodI->getOpeningDate(), 'dateClosing' => $periodI->getClosingDate(), 'date' => $periodAfterI->getOpeningDate(), ]; } ++$i; } return true; } /** * Set the Person file as closed at the given date. * * For update a closing date, you should update AccompanyingPeriod instance * directly. * * To check if the Person and its accompanying period are consistent, use validation. * * @throws Exception if two lines of the accompanying period are open. */ public function close(?AccompanyingPeriod $accompanyingPeriod = null): void { $this->proxyAccompanyingPeriodOpenState = false; } /** * This public function is the same but return only true or false. */ public function containsAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): bool { return ($this->participationsContainAccompanyingPeriod($accompanyingPeriod)) ? false : true; } /** * Get AccompanyingPeriodParticipations Collection. */ public function getAccompanyingPeriodParticipations(): Collection { return $this->accompanyingPeriodParticipations; } /** * Get AccompanyingPeriods array. */ public function getAccompanyingPeriods(): array { $accompanyingPeriods = []; foreach ($this->accompanyingPeriodParticipations as $participation) { /** @var AccompanyingPeriodParticipation $participation */ $accompanyingPeriods[] = $participation->getAccompanyingPeriod(); } return $accompanyingPeriods; } /** * Get the accompanying periods of a give person with the chronological order. */ public function getAccompanyingPeriodsOrdered(): array { $periods = $this->getAccompanyingPeriods(); //order by date : usort($periods, static function ($a, $b) { $dateA = $a->getOpeningDate(); $dateB = $b->getOpeningDate(); if ($dateA === $dateB) { $dateEA = $a->getClosingDate(); $dateEB = $b->getClosingDate(); if ($dateEA === $dateEB) { return 0; } if ($dateEA < $dateEB) { return -1; } return +1; } if ($dateA < $dateB) { return -1; } return 1; }); return $periods; } /** * By default, the addresses are ordered by date, descending (the most * recent first). * * @return \Chill\MainBundle\Entity\Address[] */ public function getAddresses() { return $this->addresses; } public function getAltNames(): Collection { return $this->altNames; } /** * Get birthdate. * * @return DateTime */ public function getBirthdate() { return $this->birthdate; } /** * Get center. * * @return Center */ public function getCenter() { return $this->center; } /** * Get cFData. * * @return array */ public function getCFData() { if (null === $this->cFData) { $this->cFData = []; } return $this->cFData; } /** * Get contactInfo. * * @return string */ public function getcontactInfo() { return $this->contactInfo; } /** * Get countryOfBirth. * * @return Chill\MainBundle\Entity\Country */ public function getCountryOfBirth() { return $this->countryOfBirth; } /** * Returns the opened accompanying period. * * @deprecated since 1.1 use `getOpenedAccompanyingPeriod instead */ public function getCurrentAccompanyingPeriod(): AccompanyingPeriod { return $this->getOpenedAccompanyingPeriod(); } /** * Get email. * * @return string */ public function getEmail() { return $this->email; } /** * Get firstName. * * @return string */ public function getFirstName() { return $this->firstName; } public function getFullnameCanonical(): string { return $this->fullnameCanonical; } /** * Get gender. * * @return string */ public function getGender() { return $this->gender; } /** * return gender as a Numeric form. * This is used for translations. * * @return int */ public function getGenderNumeric() { if ($this->getGender() === self::FEMALE_GENDER) { return 1; } return 0; } /** * Get id. * * @return int */ public function getId() { return $this->id; } /** * @return string */ public function getLabel() { return $this->getFirstName() . ' ' . $this->getLastName(); } /** * @return null */ public function getLastAddress(?DateTime $date = null) { if (null === $date) { $date = new DateTime('now'); } $addresses = $this->getAddresses(); if (null === $addresses) { return null; } return $addresses->first(); } /** * Get lastName. * * @return string */ public function getLastName() { return $this->lastName; } /** * Get maritalStatus. * * @return MaritalStatus */ public function getMaritalStatus() { return $this->maritalStatus; } /** * Get memo. * * @return string */ public function getMemo() { return $this->memo; } /** * Get mobilenumber. * * @return string */ public function getMobilenumber() { return $this->mobilenumber; } /** * Get nationality. * * @return Chill\MainBundle\Entity\Country */ public function getNationality() { return $this->nationality; } /** * Return the opened accompanying period. */ public function getOpenedAccompanyingPeriod(): ?AccompanyingPeriod { if ($this->isOpen() === false) { return null; } foreach ($this->accompanyingPeriodParticipations as $participation) { /** @var AccompanyingPeriodParticipation $participation */ if ($participation->getAccompanyingPeriod()->isOpen()) { return $participation->getAccompanyingPeriod(); } } } public function getOtherPhoneNumbers(): Collection { return $this->otherPhoneNumbers; } /** * Get phonenumber. * * @return string */ public function getPhonenumber() { return $this->phonenumber; } /** * Get placeOfBirth. * * @return string */ public function getPlaceOfBirth() { return $this->placeOfBirth; } /** * Get spokenLanguages. * * @return ArrayCollection */ public function getSpokenLanguages() { return $this->spokenLanguages; } /** * Return true if the person has two addresses with the * same validFrom date (in format 'Y-m-d'). */ public function hasTwoAdressWithSameValidFromDate() { $validYMDDates = []; foreach ($this->addresses as $ad) { $validDate = $ad->getValidFrom()->format('Y-m-d'); if (in_array($validDate, $validYMDDates, true)) { return true; } $validYMDDates[] = $validDate; } return false; } /** * Validation callback that checks if the accompanying periods are valid. * * This method add violation errors. */ public function isAccompanyingPeriodValid(ExecutionContextInterface $context) { $r = $this->checkAccompanyingPeriodsAreNotCollapsing(); if (true !== $r) { if (self::ERROR_PERIODS_ARE_COLLAPSING === $r['result']) { $context->buildViolation('Two accompanying periods have days in commun') ->atPath('accompanyingPeriods') ->addViolation(); } if (self::ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD === $r['result']) { $context->buildViolation('A period is opened and a period is added after it') ->atPath('accompanyingPeriods') ->addViolation(); } } } /** * Validation callback that checks if the addresses are valid (do not have * two addresses with the same validFrom date). * * This method add violation errors. */ public function isAddressesValid(ExecutionContextInterface $context) { if ($this->hasTwoAdressWithSameValidFromDate()) { $context ->buildViolation('Two addresses has the same validFrom date') ->atPath('addresses') ->addViolation(); } } /** * Check if the person is opened. */ public function isOpen(): bool { foreach ($this->getAccompanyingPeriods() as $period) { if ($period->isOpen()) { return true; } } return false; } /** * set the Person file as open at the given date. * * For updating a opening's date, you should update AccompanyingPeriod instance * directly. * * For closing a file, @see this::close * * To check if the Person and its accompanying period is consistent, use validation. */ public function open(AccompanyingPeriod $accompanyingPeriod): void { $this->proxyAccompanyingPeriodOpenState = true; $this->addAccompanyingPeriod($accompanyingPeriod); } /** * Remove AccompanyingPeriod. */ public function removeAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): void { $participation = $this->participationsContainAccompanyingPeriod($accompanyingPeriod); if (!null === $participation) { $participation->setEndDate(DateTimeImmutable::class); $this->accompanyingPeriodParticipations->removeElement($participation); } } public function removeAddress(Address $address) { $this->addresses->removeElement($address); } /** * @return $this */ public function removeAltName(PersonAltName $altName) { if ($this->altNames->contains($altName)) { $altName->setPerson(null); $this->altNames->removeElement($altName); } return $this; } /** * @return $this */ public function removeOtherPhoneNumber(PersonPhone $otherPhoneNumber) { if ($this->otherPhoneNumbers->contains($otherPhoneNumber)) { $this->otherPhoneNumbers->removeElement($otherPhoneNumber); } return $this; } /** * @return $this */ public function setAltNames(Collection $altNames) { $this->altNames = $altNames; return $this; } /** * Set birthdate. * * @param DateTime $birthdate * * @return Person */ public function setBirthdate($birthdate) { $this->birthdate = $birthdate; return $this; } /** * Set the center. * * @return \Chill\PersonBundle\Entity\Person */ public function setCenter(Center $center) { $this->center = $center; return $this; } /** * Set cFData. * * @param array $cFData * * @return Report */ public function setCFData($cFData) { $this->cFData = $cFData; return $this; } /** * Set contactInfo. * * @param string $contactInfo * * @return Person */ public function setcontactInfo($contactInfo) { if (null === $contactInfo) { $contactInfo = ''; } $this->contactInfo = $contactInfo; return $this; } /** * Set countryOfBirth. * * @param Chill\MainBundle\Entity\Country $countryOfBirth * * @return Person */ public function setCountryOfBirth(?Country $countryOfBirth = null) { $this->countryOfBirth = $countryOfBirth; return $this; } /** * Set email. * * @param string $email * * @return Person */ public function setEmail($email) { if (null === $email) { $email = ''; } $this->email = $email; return $this; } /** * Set firstName. * * @param string $firstName * * @return Person */ public function setFirstName($firstName) { $this->firstName = $firstName; return $this; } public function setFullnameCanonical($fullnameCanonical): Person { $this->fullnameCanonical = $fullnameCanonical; return $this; } /** * Set gender. * * @param string $gender * * @return Person */ public function setGender($gender) { $this->gender = $gender; return $this; } /** * Set lastName. * * @param string $lastName * * @return Person */ public function setLastName($lastName) { $this->lastName = $lastName; return $this; } /** * Set maritalStatus. * * @param MaritalStatus $maritalStatus * * @return Person */ public function setMaritalStatus(?MaritalStatus $maritalStatus = null) { $this->maritalStatus = $maritalStatus; return $this; } /** * Set memo. * * @param string $memo * * @return Person */ public function setMemo($memo) { if (null === $memo) { $memo = ''; } if ($this->memo !== $memo) { $this->memo = $memo; } return $this; } /** * Set mobilenumber. * * @param string $mobilenumber * * @return Person */ public function setMobilenumber($mobilenumber = '') { $this->mobilenumber = $mobilenumber; return $this; } /** * Set nationality. * * @param Chill\MainBundle\Entity\Country $nationality * * @return Person */ public function setNationality(?Country $nationality = null) { $this->nationality = $nationality; return $this; } /** * @return $this */ public function setOtherPhoneNumbers(Collection $otherPhoneNumbers) { $this->otherPhoneNumbers = $otherPhoneNumbers; return $this; } /** * Set phonenumber. * * @param string $phonenumber * * @return Person */ public function setPhonenumber($phonenumber = '') { $this->phonenumber = $phonenumber; return $this; } /** * Set placeOfBirth. * * @param string $placeOfBirth * * @return Person */ public function setPlaceOfBirth($placeOfBirth) { if (null === $placeOfBirth) { $placeOfBirth = ''; } $this->placeOfBirth = $placeOfBirth; return $this; } /** * Set spokenLanguages. * * @param type $spokenLanguages * * @return Person */ public function setSpokenLanguages($spokenLanguages) { $this->spokenLanguages = $spokenLanguages; return $this; } /** * This private function scan accompanyingPeriodParticipations Collection, * searching for a given AccompanyingPeriod. */ private function participationsContainAccompanyingPeriod(AccompanyingPeriod $accompanyingPeriod): ?AccompanyingPeriodParticipation { foreach ($this->accompanyingPeriodParticipations as $participation) { /** @var AccompanyingPeriodParticipation $participation */ if ($participation->getAccompanyingPeriod() === $accompanyingPeriod) { return $participation; } } return null; } }