<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\BooleanFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Serializer\Filter\PropertyFilter;
use App\Validator\SurveyFormAnswerAssociation;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Greg0ire\Enum\Bridge\Symfony\Validator\Constraint\Enum as EnumAssert;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="App\Repository\SurveyFormQuestionRepository")
* @ORM\HasLifecycleCallbacks()
* @SurveyFormAnswerAssociation()
*/
#[ApiResource(
attributes: ['security' => "is_granted('ROLE_USER')"],
collectionOperations: ['get', 'post' => ['security' => "is_granted('ROLE_ADMIN')"]],
itemOperations: ['get', 'put' => ['security' => "is_granted('ROLE_ADMIN') or object.owner == user"], 'delete' => ['security' => "is_granted('ROLE_ADMIN')"]],
)]
#[ApiFilter(PropertyFilter::class)]
#[ApiFilter(OrderFilter::class, properties: ['id', 'type', 'category.title', 'label', 'ratingActivated', 'isUpdateProfile', 'isActive', 'demographicsType', 'createdAt'], arguments: ['orderParameterName' => 'order'])]
#[ApiFilter(BooleanFilter::class, properties: ['isUpdateProfile'])]
class SurveyFormQuestion
{
use TimestampableEntity;
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"pinpointCampaign:list"})
*/
private $id;
/**
* @var string
*
* @ORM\Column(type="string", length=64)
* @Assert\Length(max="64")
* @Assert\NotBlank()
* @EnumAssert(class="App\Enum\SurveyFormQuestionType")
* @Groups({"pinpointCampaign:list"})
*/
#[ApiFilter(SearchFilter::class, strategy: 'exact')]
private $type;
/**
* @var bool
*
* @ORM\Column(type="boolean")
*/
private $ratingActivated;
/**
* @var string
*
* @ORM\Column(type="text")
* @Assert\NotBlank()
* @Groups({"pinpointCampaign:list"})
*/
#[ApiFilter(SearchFilter::class, strategy: 'ipartial')]
private $label;
/**
* @var string
*
* @ORM\Column(type="string", length=2000, nullable=true)
* @Assert\Length(max="2000")
*/
#[ApiFilter(SearchFilter::class, strategy: 'ipartial')]
private $info;
/**
* @var string
*
* @ORM\Column(type="string", length=128, nullable=true)
* @Assert\Length(max="128")
* @Groups({"pinpointCampaign:list"})
*/
private $placeholder;
/**
* @var string
*
* @ORM\Column(type="string", length=128, nullable=true)
* @Assert\Length(max="128")
* @Groups({"pinpointCampaign:list"})
*/
private $sliderLabelMin;
/**
* @var string
*
* @ORM\Column(type="string", length=128, nullable=true)
* @Assert\Length(max="128")
* @Groups({"pinpointCampaign:list"})
*/
private $sliderLabelMax;
/**
* @var int
*
* @ORM\Column(type="integer")
* @Assert\NotBlank()
* @Assert\Type(type="integer")
* @Groups({"pinpointCampaign:list"})
*/
private $position;
/**
* @var string
*
* @ORM\Column(type="string", length=64, nullable=true)
* @Assert\Length(max="64")
* @EnumAssert(class="App\Enum\SurveyFormType")
*/
private $demographicsType;
/**
* @var SurveyFormStep
*
* @ORM\ManyToOne(targetEntity="App\Entity\SurveyFormStep")
* @ORM\JoinColumn(nullable=true, name="form_step_id", referencedColumnName="id")
*/
private $formStep;
/**
* @var Category
*
* @ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="surveyFormQuestions")
* @ORM\JoinColumn(nullable=true)
* @Groups({"pinpointCampaign:list"})
*/
#[ApiFilter(SearchFilter::class)]
private $category;
/**
* @var int
*
* @ORM\Column(type="integer")
* @Assert\Type(type="integer")
* @Groups({"pinpointCampaign:list"})
*/
private $maxSelection;
/**
* @ORM\Column(type="boolean")
* @Groups({"pinpointCampaign:list"})
*/
private $isActive;
/**
* @ORM\Column(type="boolean")
* @Groups({"pinpointCampaign:list"})
*/
private $isUpdateProfile;
/**
* @var string
*
* @ORM\Column(type="string", length=100, nullable=true)
* @Assert\Length(max="100")
* @Groups({"pinpointCampaign:list"})
*/
private $profileFieldName;
/**
* @var string
*
* @ORM\Column(type="string", length=100, nullable=true)
* @Assert\Length(max="100")
* @Groups({"pinpointCampaign:list"})
*/
private $otherAnswerText;
/**
* @var string
*
* @ORM\Column(type="string", length=100, nullable=true)
* @Assert\Length(max="100")
*/
private $subType;
/**
* @var string
*
* @ORM\Column(type="string", length=10, nullable=true)
* @Assert\Length(max="10")
*/
private $isSubType;
/**
* @var ArrayCollection|SurveyFormStep[]
*
* @ORM\ManyToMany(targetEntity="App\Entity\SurveyFormStep", mappedBy="formQuestions")
* @ORM\JoinColumn(name="survey_form_step_id", referencedColumnName="id")
* @ORM\OrderBy({"id" = "ASC"})
*/
private $formSteps;
/**
* @var ArrayCollection|SurveyFormStepSurveyFormQuestion[]
*
* @ORM\OneToMany(targetEntity="App\Entity\SurveyFormStepSurveyFormQuestion", mappedBy="surveyFormQuestion", cascade={"persist"}))
* @ORM\JoinColumn(name="id", referencedColumnName="survey_form_question_id")
* @ORM\OrderBy({"id" = "ASC"})
*/
private $surveyFormSteps;
/**
* @var ArrayCollection|SurveyCompanySurveyFormQuestion[]
*
* @ORM\OneToMany(targetEntity="App\Entity\SurveyCompanySurveyFormQuestion", mappedBy="surveyFormQuestion", cascade={"persist"}))
* @ORM\JoinColumn(name="id", referencedColumnName="survey_form_question_id")
* @ORM\OrderBy({"id" = "ASC"})
*/
private $surveyCompanies;
/**
* @var ArrayCollection|SurveyFormAnswer[]
*
* @ORM\OneToMany(targetEntity="App\Entity\SurveyFormAnswer", mappedBy="formQuestion",orphanRemoval=true, cascade={"persist","remove"})
* @ORM\OrderBy({"other" = "ASC","position" = "ASC"})
* @Groups({"pinpointCampaign:list"})
*/
private iterable $formAnswers;
/**
* @var DateTimeTypeAnswer
*
* @ORM\OneToOne(targetEntity=DateTimeTypeAnswer::class, mappedBy="formQuestion", orphanRemoval=true, cascade={"persist", "remove"})
* @Groups({"pinpointCampaign:list"})
*/
private $dateTimeTypeAnswer;
/** @var FileTypeAnswer
* @ORM\OneToOne(targetEntity=FileTypeAnswer::class, mappedBy="formQuestion", orphanRemoval=true, cascade={"persist", "remove"})
* @Groups({"pinpointCampaign:list"})
*/
private $fileTypeAnswer;
/**
* @ORM\Column(type="boolean", nullable=true)
*/
private $hasOtherFormAnswer;
public function __construct()
{
$this->position = 0;
$this->isActive = true;
$this->isUpdateProfile = false;
$this->ratingActivated = false;
$this->maxSelection = 0;
$this->isSubType = 'no';
$this->hasOtherFormAnswer = false;
$this->formSteps = new ArrayCollection();
$this->formAnswers = new ArrayCollection();
$this->surveyFormSteps = new ArrayCollection();
$this->surveyCompanies = new ArrayCollection();
}
public function __toString()
{
return $this->getId() . ') ' . $this->getLabel();
}
public function getId(): ?int
{
return $this->id;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(string $type): self
{
$this->type = $type;
return $this;
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): self
{
$this->label = $label;
return $this;
}
public function getInfo(): ?string
{
return $this->info;
}
public function setInfo(?string $info): self
{
$this->info = $info;
return $this;
}
public function getPlaceholder(): ?string
{
return $this->placeholder;
}
public function setPlaceholder(?string $placeholder): self
{
$this->placeholder = $placeholder;
return $this;
}
public function getSliderLabelMin(): ?string
{
return $this->sliderLabelMin;
}
public function setSliderLabelMin(?string $sliderLabelMin): self
{
$this->sliderLabelMin = $sliderLabelMin;
return $this;
}
public function getSliderLabelMax(): ?string
{
return $this->sliderLabelMax;
}
public function setSliderLabelMax(?string $sliderLabelMax): self
{
$this->sliderLabelMax = $sliderLabelMax;
return $this;
}
public function getPosition(): ?int
{
return $this->position;
}
public function setPosition(int $position): self
{
$this->position = $position;
return $this;
}
public function getMaxSelection(): ?int
{
return $this->maxSelection;
}
public function setMaxSelection(?int $maxSelection): self
{
$this->maxSelection = $maxSelection;
return $this;
}
/**
* @return Collection<int, SurveyFormAnswer>
*/
public function getFormAnswers(): iterable
{
$this->formAnswers->filter(function ($item, $i) {
if (!$item->getPosition() && $item->getOther()) {
return $item->setPosition($i * 3);
}
return $item;
});
return $this->formAnswers;
}
public function addFormAnswer(?SurveyFormAnswer $formAnswer): self
{
if (!$this->formAnswers->contains($formAnswer)) {
$this->formAnswers[] = $formAnswer;
$formAnswer->setFormQuestion($this);
}
return $this;
}
public function removeFormAnswer(?SurveyFormAnswer $formAnswer): self
{
if ($this->formAnswers->contains($formAnswer)) {
$this->formAnswers->removeElement($formAnswer);
// set the owning side to null (unless already changed)
if ($formAnswer->getFormQuestion() === $this) {
$formAnswer->setFormQuestion(null);
}
}
return $this;
}
public function getOtherAnswerText(): ?string
{
return $this->otherAnswerText;
}
public function setOtherAnswerText(?string $otherAnswerText): self
{
$this->otherAnswerText = $otherAnswerText;
return $this;
}
public function getRatingActivated(): ?bool
{
return $this->ratingActivated;
}
public function setRatingActivated(bool $ratingActivated): self
{
$this->ratingActivated = $ratingActivated;
return $this;
}
public function getDemographicsType(): ?string
{
return $this->demographicsType;
}
public function setDemographicsType(?string $demographicsType): self
{
$this->demographicsType = $demographicsType;
return $this;
}
public function getIsActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
public function getIsUpdateProfile(): ?bool
{
return $this->isUpdateProfile;
}
public function setIsUpdateProfile(bool $isUpdateProfile): self
{
$this->isUpdateProfile = $isUpdateProfile;
return $this;
}
public function getProfileFieldName(): ?string
{
return $this->profileFieldName;
}
public function setProfileFieldName(?string $profileFieldName): self
{
$this->profileFieldName = $profileFieldName;
return $this;
}
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
$this->category = $category;
return $this;
}
/**
* @return Collection|SurveyFormStep[]
*/
public function getFormSteps(): Collection
{
return $this->formSteps;
}
public function addFormStep(SurveyFormStep $formSteps): self
{
if (!$this->formSteps->contains($formSteps)) {
$this->formSteps[] = $formSteps;
$formSteps->addFormQuestion($this);
}
return $this;
}
public function removeFormStep(SurveyFormStep $formSteps): self
{
if ($this->formSteps->contains($formSteps)) {
$this->formSteps->removeElement($formSteps);
$formSteps->removeFormQuestion($this);
}
return $this;
}
/**
* @return Collection|SurveyFormStepSurveyFormQuestion[]
*/
public function getSurveyFormSteps(): Collection
{
return $this->surveyFormSteps;
}
// public function addSurveyFormStep(SurveyFormStepSurveyFormQuestion $surveyFormStep): self
// {
// if (!$this->surveyFormSteps->contains($surveyFormStep)) {
// $surveyFormStep->setSurveyFormQuestion($this);
// $this->surveyFormSteps[] = $surveyFormStep;
// }
// return $this;
// }
// public function removeSurveyFormStep(SurveyFormStepSurveyFormQuestion $surveyFormStep): self
// {
// if ($this->surveyFormSteps->contains($surveyFormStep)) {
// $this->surveyFormSteps->removeElement($surveyFormStep);
// // set the owning side to null (unless already changed)
// if ($surveyFormStep->getSurveyFormQuestion() === $this) {
// $surveyFormStep->setSurveyFormQuestion(null);
// }
// }
// return $this;
// }
/**
* @return Collection|SurveyCompanySurveyFormQuestion[]
*/
public function getSurveyCompanies(): Collection
{
return $this->surveyCompanies;
}
public function addSurveyCompany(SurveyCompany $surveyCompany): self
{
if (!$this->surveyCompanies->contains($surveyCompany)) {
$surveyCompany->setSurveyCompany($this);
$this->surveyCompanies[] = $surveyCompany;
}
return $this;
}
public function removeSurveyCompany(SurveyCompany $surveyCompany): self
{
if ($this->surveyCompanies->contains($surveyCompany)) {
$this->surveyCompanies->removeElement($surveyCompany);
// set the owning side to null (unless already changed)
if ($surveyCompany->getSurveyCompany() === $this) {
$surveyCompany->setSurveyCompany(null);
}
}
return $this;
}
public function getSubType(): ?string
{
return $this->subType;
}
public function setSubType(?string $subType): self
{
$this->subType = $subType;
return $this;
}
public function getIsSubType(): ?string
{
return $this->isSubType;
}
public function setIsSubType(string $isSubType): self
{
$this->isSubType = $isSubType;
return $this;
}
public function getDateTimeTypeAnswer(): ?DateTimeTypeAnswer
{
return $this->dateTimeTypeAnswer;
}
public function setDateTimeTypeAnswer(?DateTimeTypeAnswer $dateTimeTypeAnswer): self
{
// unset the owning side of the relation if necessary
if (null === $dateTimeTypeAnswer && null !== $this->dateTimeTypeAnswer) {
$this->dateTimeTypeAnswer->setFormQuestion(null);
}
// set the owning side of the relation if necessary
if (null !== $dateTimeTypeAnswer && $dateTimeTypeAnswer->getFormQuestion() && $dateTimeTypeAnswer->getFormQuestion()->getId() !== $this->getId()) {
$dateTimeTypeAnswer->setFormQuestion($this);
$this->dateTimeTypeAnswer = $dateTimeTypeAnswer;
}
// set the owning side of the relation if necessary
if (null !== $dateTimeTypeAnswer && $dateTimeTypeAnswer->getFormQuestion() && $dateTimeTypeAnswer->getFormQuestion()->getId() == $this->getId()) {
$dateTimeTypeAnswer->setFormQuestion($this);
$this->dateTimeTypeAnswer->setDateFormat($dateTimeTypeAnswer->getDateFormat());
$this->dateTimeTypeAnswer->setDateTime($dateTimeTypeAnswer->getDateTime());
$this->dateTimeTypeAnswer->setErrorMessage($dateTimeTypeAnswer->getErrorMessage());
} elseif (null !== $dateTimeTypeAnswer && null === $dateTimeTypeAnswer->getFormQuestion()) {
$dateTimeTypeAnswer->setFormQuestion($this);
$this->dateTimeTypeAnswer = $dateTimeTypeAnswer;
}
return $this;
}
public function getFileTypeAnswer(): ?FileTypeAnswer
{
return $this->fileTypeAnswer;
}
public function setFileTypeAnswer(?FileTypeAnswer $fileTypeAnswer): self
{
// unset the owning side of the relation if necessary
if (null === $fileTypeAnswer && null !== $this->fileTypeAnswer) {
$this->fileTypeAnswer->setFormQuestion(null);
}
// set the owning side of the relation if necessary
if (null !== $fileTypeAnswer && $fileTypeAnswer->getFormQuestion() && $fileTypeAnswer->getFormQuestion()->getId() !== $this->getId()) {
$fileTypeAnswer->setFormQuestion($this);
$this->fileTypeAnswer = $fileTypeAnswer;
}
// set the owning side of the relation if necessary
if (null !== $fileTypeAnswer && $fileTypeAnswer->getFormQuestion() && $fileTypeAnswer->getFormQuestion()->getId() == $this->getId()) {
$this->fileTypeAnswer->setAllowedFiles($fileTypeAnswer->getAllowedFiles());
$this->fileTypeAnswer->setTypeErrorMessage($fileTypeAnswer->getTypeErrorMessage());
} elseif (null !== $fileTypeAnswer && null === $fileTypeAnswer->getFormQuestion()) {
$fileTypeAnswer->setFormQuestion($this);
$this->fileTypeAnswer = $fileTypeAnswer;
}
return $this;
}
/**
* @var float
*/
public function getAverageRating(): float
{
$maxScore = 0.00;
if (array_search($this->type, ['choice-unique-collapsed', 'choice-unique-expanded']) && $this->formAnswers->count() > 0) {
$totalRating = [];
foreach ($this->formAnswers as $ans) {
$totalRating[] = (float) $ans->getRating();
}
$maxScore = max($totalRating);
}
return $maxScore;
}
public function getHasOtherFormAnswer(): ?bool
{
return $this->hasOtherFormAnswer;
}
public function setHasOtherFormAnswer(?bool $hasOtherFormAnswer): self
{
$this->hasOtherFormAnswer = $hasOtherFormAnswer;
return $this;
}
}