You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
875 lines
24 KiB
875 lines
24 KiB
<?php |
|
|
|
namespace App\Entity; |
|
|
|
use App\Traits\RandomTrait; |
|
use App\Traits\TimeStampableTrait; |
|
use DateTime; |
|
use DateTimeInterface; |
|
use Doctrine\Common\Collections\ArrayCollection; |
|
use Doctrine\Common\Collections\Collection; |
|
use Doctrine\ORM\Mapping as ORM; |
|
use ErrorException; |
|
use JMS\Serializer\Annotation as Serializer; |
|
|
|
/** |
|
* @ORM\Entity(repositoryClass="App\Repository\PollRepository") |
|
* @Serializer\ExclusionPolicy("all") |
|
*/ |
|
class Poll |
|
{ |
|
|
|
use RandomTrait; |
|
|
|
use TimeStampableTrait; |
|
|
|
/** |
|
* @ORM\Id() |
|
* @ORM\GeneratedValue() |
|
* @ORM\Column(type="integer") |
|
* @Serializer\Expose() |
|
* @Serializer\Type("integer") |
|
*/ |
|
public $id; |
|
|
|
/** |
|
* @ORM\Column(type="string", length=255) |
|
* @Serializer\Expose() |
|
* @Serializer\Type("string") |
|
*/ |
|
public $title; |
|
/** |
|
* @ORM\Column(type="string", length=255, nullable=false, unique=true) |
|
* @Serializer\Expose() |
|
* @Serializer\Type("string") |
|
*/ |
|
public $customUrl; |
|
/** |
|
* @ORM\Column(type="string", length=1000) |
|
* @Serializer\Expose() |
|
* @Serializer\Type("string") |
|
*/ |
|
public $description; |
|
|
|
/** |
|
* @ORM\Column(type="datetime") |
|
* @Serializer\Expose() |
|
*/ |
|
public $expiracyDate; |
|
/** |
|
* @ORM\ManyToOne(targetEntity="App\Entity\Owner", inversedBy="polls",cascade={"persist"}) |
|
* @ORM\JoinColumn(nullable=false) |
|
* @Serializer\Type("App\Entity\Owner") |
|
* @Serializer\Expose() |
|
*/ |
|
public $owner; |
|
/** |
|
* kind of poll, 'text' or 'date' |
|
* @ORM\Column(type="string", length=255) |
|
* @Serializer\Type("string") |
|
* @Serializer\Expose() |
|
*/ |
|
public $kind = 'text'; |
|
/** |
|
* array of possible answer to each choice, by default: "yes" or nothing only. |
|
* could be also "yes", "maybe", "no". extensible to anything |
|
* @ORM\Column(type="array") |
|
* @Serializer\Type("array") |
|
* @Serializer\Expose() |
|
*/ |
|
public $allowedAnswers; |
|
|
|
/** |
|
* people can add votes |
|
* @ORM\Column(type="boolean", nullable=true) |
|
* @Serializer\Type("boolean") |
|
* @Serializer\Expose() |
|
*/ |
|
public $votesAllowed = true; |
|
|
|
/** |
|
* people can add votes |
|
* @ORM\Column(type="boolean", nullable=true) |
|
* @Serializer\Type("boolean") |
|
* @Serializer\Expose() |
|
*/ |
|
public $isZeroKnowledge; |
|
|
|
/** |
|
* max number of stack of votes possible. |
|
* limits the number of people who can answer. as long as you trust the people to give only one answer with a reliable system. |
|
* @ORM\Column(type="smallint", nullable=true) |
|
* @Serializer\Type("smallint") |
|
* @Serializer\Expose() |
|
*/ |
|
public $votesMax = 1024*10; |
|
|
|
/** |
|
* max number of choices people can answer in a stack of vote. for text polls only, not date kind. |
|
* by default, people can check as many answers as they want. |
|
* If the question is "check your 3 favourite flavours" and displays 10 flavours, only the first 3 clicked will be taken into account. GUI should be able to make this clear and togglable so that people can change their 3 favourite flavours in their answer. |
|
* @ORM\Column(type="smallint", nullable=true) |
|
* @Serializer\Type("smallint") |
|
* @Serializer\Expose() |
|
*/ |
|
public $choicesMax = -1; |
|
|
|
/** |
|
* people can add comments |
|
* @ORM\Column(type="boolean", nullable=true) |
|
* @Serializer\Type("boolean") |
|
* @Serializer\Expose() |
|
*/ |
|
public $commentsAllowed = true; |
|
|
|
/** |
|
* kind of way the people can modify the poll |
|
* everybody - can modify votes |
|
* self - one can only modify its own vote |
|
* nobody - no one can modify the votes (excepted admin), pray to have it right at first |
|
* @ORM\Column(type="string", length=255) |
|
* @Serializer\Type("string") |
|
* @Serializer\Expose() |
|
*/ |
|
public $modificationPolicy = 'everybody'; |
|
/** |
|
* send a mail on a new comment |
|
* @ORM\Column(type="boolean", nullable=true) |
|
* @Serializer\Type("boolean") |
|
* @Serializer\Expose() |
|
*/ |
|
public $mailOnComment = true; |
|
/** |
|
* send a mail on a new vote |
|
* @ORM\Column(type="boolean", nullable=true) |
|
* @Serializer\Type("boolean") |
|
* @Serializer\Expose() |
|
*/ |
|
public $mailOnVote = false; |
|
/** |
|
* hide publicly results |
|
* @ORM\Column(type="boolean", nullable=true) |
|
* @Serializer\Type("boolean") |
|
* @Serializer\Expose() |
|
*/ |
|
public $hideResults = false; |
|
/** |
|
* show publicly results even if there is a password to access the vote |
|
* @ORM\Column(type="boolean", nullable=true) |
|
* @Serializer\Type("boolean") |
|
* @Serializer\Expose() |
|
*/ |
|
public $showResultEvenIfPasswords = false; |
|
/** |
|
* @ORM\OneToMany(targetEntity="App\Entity\Vote", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"}) |
|
* @Serializer\Type("ArrayCollection<App\Entity\Vote>") |
|
* @Serializer\Expose() |
|
*/ |
|
public $votes; |
|
/** |
|
* @ORM\OneToMany(targetEntity="App\Entity\StackOfVotes", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"}) |
|
* @Serializer\Expose() |
|
*/ |
|
public $stacksOfVotes; |
|
/** |
|
* @ORM\OneToMany(targetEntity="App\Entity\Choice", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"}) |
|
* @Serializer\Expose() |
|
* @Serializer\Type("ArrayCollection<App\Entity\Choice>") |
|
*/ |
|
public $choices; |
|
/** |
|
* @ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="poll", orphanRemoval=true, cascade={"persist", "remove"}) |
|
* @Serializer\Expose() |
|
* @Serializer\Type("ArrayCollection<App\Entity\Comment>") |
|
*/ |
|
public $comments; |
|
/** |
|
* number of days from now for default expiracy date |
|
* @var int |
|
* @Serializer\Expose() |
|
*/ |
|
public $defaultExpiracyDaysFromNow = 60; |
|
/** |
|
* vote restricted by a password in md5 format |
|
* @ORM\Column(type="string", length=255, nullable=true) |
|
*/ |
|
private $password; |
|
/** |
|
* used to allow administration |
|
* @ORM\Column(type="string", length=255) |
|
* @Serializer\Type("string") |
|
*/ |
|
private $adminKey; |
|
private $maxChoicesLimit = 25; |
|
|
|
public function __construct() |
|
{ |
|
|
|
$this->initiate(); |
|
$this->setCreatedAt(new DateTime()); |
|
$this->setAdminKey($this->generateRandomKey()); |
|
$this->votes = new ArrayCollection(); |
|
$this->stacksOfVotes = new ArrayCollection(); |
|
$this->choices = new ArrayCollection(); |
|
$this->comments = new ArrayCollection(); |
|
} |
|
|
|
private function initiate() |
|
{ |
|
$this->votes = new ArrayCollection(); |
|
$this->stacksOfVotes = new ArrayCollection(); |
|
$this->choices = new ArrayCollection(); |
|
$this->comments = new ArrayCollection(); |
|
$this->setAdminKey($this->generateRandomKey()); |
|
$this->setCreatedAt(new DateTime()); |
|
$this->setExpiracyDate($this->addDaysToDate( |
|
new DateTime(), |
|
$this->defaultExpiracyDaysFromNow |
|
)); |
|
$this->setAllowedAnswers(['yes', 'maybe', 'no']); |
|
} |
|
|
|
public function setCreatedAt(DateTimeInterface $createdAt): self |
|
{ |
|
$this->createdAt = $createdAt; |
|
|
|
return $this; |
|
} |
|
|
|
public function displayForAdmin() |
|
{ |
|
$content = $this->display(); |
|
$content['owner'] = $this->getOwner()->displayForAdmin(); |
|
$content['admin_key'] = $this->getAdminKey(); |
|
$content['password_hash'] = $this->getPassword(); |
|
$content['id'] = $this->getId(); |
|
ksort($content); |
|
return $content; |
|
} |
|
|
|
// counts each number of answer for this choice |
|
|
|
public function display(): array |
|
{ |
|
|
|
$computedAnswers = $this->computeAnswers(); |
|
$displayedStackOfVotes = []; |
|
foreach ($this->getStacksOfVotes() as $stack) { |
|
$displayedStackOfVotes[] = $stack->display(); |
|
} |
|
$displayedChoices = []; |
|
foreach ($this->getChoices() as $choice) { |
|
$displayedChoices[] = $choice->display($this->getKind()); |
|
} |
|
$displayedComments = []; |
|
foreach ($this->getComments() as $comment) { |
|
$displayedComments[] = $comment->display(); |
|
} |
|
|
|
|
|
$resp = [ |
|
'allowed_answers' => $this->getAllowedAnswers(), |
|
'choices' => $computedAnswers['answers'], |
|
'choices_grouped' => $computedAnswers['grouped_dates'], |
|
'choices_max' => $this->getChoicesMax(), |
|
'comments' => $displayedComments, |
|
'created_at' => $this->getCreatedAt()->format('c'), |
|
'custom_url' => $this->getCustomUrl(), |
|
'description' => $this->getDescription(), |
|
'expiracy_date' => $this->getExpiracyDate()->format('c'), |
|
'hide_results' => $this->getHideResults(), |
|
'kind' => $this->getKind(), |
|
'max_score' => $computedAnswers['max_score'], |
|
'modification_policy' => $this->getModificationPolicy(), |
|
'owner' => ['pseudo' => $this->getOwner()->getPseudo(),], |
|
'password_protected' => $this->getPassword() ? 'yes' : 'no', |
|
'show_results_even_if_password' => $this->getShowResultEvenIfPasswords(), |
|
'stacks' => $displayedStackOfVotes, |
|
'title' => $this->getTitle(), |
|
'votes_allowed' => $this->getVotesAllowed(), |
|
'votes_max' => $this->getVotesMax(), |
|
]; |
|
ksort($resp); |
|
|
|
return $resp; |
|
} |
|
|
|
public function computeAnswers() |
|
{ |
|
$computedArray = []; |
|
$grouped_dates = []; |
|
$maxScore = 0; |
|
|
|
if ($this->getKind() == 'date') { |
|
foreach ($this->getChoices() as $choice) { |
|
$boom = explode(' >>> ', $choice->getName()); |
|
|
|
// handle sub time slices |
|
if (count($boom) == 2) { |
|
if (!isset($grouped_dates[$boom[0]])) { |
|
|
|
$grouped_dates[$boom[0]] = [ |
|
|
|
"date_string" => $boom[0], |
|
"choices" => [], |
|
]; |
|
} |
|
$grouped_dates[$boom[0]]["choices"][] = [ |
|
"choice_id" => $choice->getId(), |
|
"name" => $boom[1], |
|
]; |
|
} elseif (count($boom) == 1) { |
|
$name = $choice->getName(); |
|
$grouped_dates[$name] = [ |
|
|
|
"date_string" => $name, |
|
"choices" => [], |
|
]; |
|
$grouped_dates[$name]["choices"][] = [ |
|
"choice_id" => $choice->getId(), |
|
"name" => $name, |
|
]; |
|
} |
|
} |
|
} elseif ($this->getKind() == 'text') { |
|
foreach ($this->getChoices() as $choice) { |
|
$name = $choice->getName(); |
|
|
|
|
|
if (!isset($grouped_dates[$name])) { |
|
|
|
$grouped_dates[$name] = [ |
|
|
|
"date_string" => $name, |
|
"choices" => [], |
|
]; |
|
} |
|
$grouped_dates[$name]["choices"][] = [ |
|
"choice_id" => $choice->getId(), |
|
"name" => $name, |
|
]; |
|
} |
|
} |
|
$scoreInfos = [ |
|
|
|
'id' => null, |
|
'name' => null, |
|
'score' => 0, |
|
'created_at' => null, |
|
'yes' => [ |
|
'count' => 0, |
|
'people' => [], |
|
], |
|
'maybe' => [ |
|
'count' => 0, |
|
'people' => [], |
|
], |
|
'no' => [ |
|
'count' => 0, |
|
'people' => [], |
|
], |
|
]; |
|
|
|
// first, prefill all choices |
|
foreach ($this->getChoices() as $choice) { |
|
$computedArray[$choice->getId()] = array_merge($scoreInfos, $choice->display($this->getKind())); |
|
} |
|
// then, compute stack of votes scores on each choice |
|
foreach ($this->getStacksOfVotes() as $stack_of_vote) { |
|
foreach ($stack_of_vote->getVotes() as $vote) { |
|
$answer = $vote->getValue(); |
|
$choice_id = $vote->getChoice()->getId(); |
|
$choice_url = $vote->getChoice()->getUrl(); |
|
|
|
if (!isset($computedArray[$choice_id])) { |
|
$computedArray[$choice_id] = [ |
|
'id' => $choice_id, |
|
'url' => $choice_url, |
|
'name' => $vote->getChoice()->getName(), |
|
'score' => 0, |
|
'yes' => [ |
|
'count' => 0, |
|
'people' => [], |
|
], |
|
'maybe' => [ |
|
'count' => 0, |
|
'people' => [], |
|
], |
|
'no' => [ |
|
'count' => 0, |
|
'people' => [], |
|
], |
|
|
|
]; |
|
} |
|
$computedArray[$choice_id][$answer]['count']++; |
|
$computedArray[$choice_id][$answer]['people'][] = $stack_of_vote->getOwner()->getPseudo(); |
|
|
|
if ($answer == 'yes') { |
|
$computedArray[$choice_id]['score'] += 1; |
|
} elseif ($answer == 'maybe') { |
|
$computedArray[$choice_id]['score'] += 0.5; |
|
} |
|
// compare with max value |
|
if ($computedArray[$choice_id]['score'] > $maxScore) { |
|
$maxScore = $computedArray[$choice_id]['score']; |
|
} |
|
} |
|
} |
|
$answersWithStats = []; |
|
foreach ($computedArray as $choice_stat) { |
|
$answersWithStats[] = $choice_stat; |
|
} |
|
$groupsOfDates = []; |
|
foreach ($grouped_dates as $group) { |
|
$ii = 0; |
|
foreach ($group["choices"] as $slice) { |
|
$slice['score'] = $computedArray[$slice['choice_id']]['score']; |
|
$slice['yes'] = $computedArray[$slice['choice_id']]['yes']; |
|
$slice['maybe'] = $computedArray[$slice['choice_id']]['maybe']; |
|
$slice['no'] = $computedArray[$slice['choice_id']]['no']; |
|
$slice['id'] = $slice['choice_id']; |
|
$group["choices"][$ii] = $slice; |
|
$ii++; |
|
} |
|
|
|
$groupsOfDates[] = $group; |
|
} |
|
|
|
return [ |
|
'answers' => $answersWithStats, |
|
'grouped_dates' => $groupsOfDates, |
|
'max_score' => $maxScore, |
|
]; |
|
} |
|
|
|
/** |
|
* @return Collection|Choice[] |
|
*/ |
|
public function getChoices(): Collection |
|
{ |
|
return $this->choices; |
|
} |
|
|
|
public function getKind(): ?string |
|
{ |
|
return $this->kind; |
|
} |
|
|
|
public function setKind(string $kind): self |
|
{ |
|
$this->kind = $kind; |
|
|
|
return $this; |
|
} |
|
|
|
public function getStacksOfVotes() |
|
{ |
|
return $this->stacksOfVotes; |
|
} |
|
|
|
public function setStacksOfVotes(?StackOfVotes $stacksOfVotes): self |
|
{ |
|
$this->stacksOfVotes = $stacksOfVotes; |
|
|
|
return $this; |
|
} |
|
|
|
/** |
|
* @return Collection|Comment[] |
|
*/ |
|
public function getComments(): Collection |
|
{ |
|
return $this->comments; |
|
} |
|
|
|
public function getTitle(): ?string |
|
{ |
|
return $this->title; |
|
} |
|
|
|
public function setTitle(string $title): self |
|
{ |
|
$this->title = $title; |
|
|
|
return $this; |
|
} |
|
|
|
public function getDescription(): ?string |
|
{ |
|
return $this->description; |
|
} |
|
|
|
public function setDescription(string $description): self |
|
{ |
|
$this->description = $description; |
|
|
|
return $this; |
|
} |
|
|
|
public function getCreatedAt(): ?DateTimeInterface |
|
{ |
|
return $this->createdAt; |
|
} |
|
|
|
public function getExpiracyDate(): ?DateTimeInterface |
|
{ |
|
return $this->expiracyDate; |
|
} |
|
|
|
public function setExpiracyDate(DateTimeInterface $expiracyDate): self |
|
{ |
|
$this->expiracyDate = $expiracyDate; |
|
|
|
return $this; |
|
} |
|
|
|
public function getVotesMax() |
|
{ |
|
return $this->votesMax; |
|
} |
|
|
|
public function setVotesMax($votesMax): self |
|
{ |
|
$this->votesMax = $votesMax; |
|
|
|
return $this; |
|
} |
|
|
|
public function getChoicesMax() |
|
{ |
|
return $this->choicesMax; |
|
} |
|
|
|
public function setChoicesMax($choicesMax): self |
|
{ |
|
$this->choicesMax = $choicesMax; |
|
|
|
return $this; |
|
} |
|
|
|
public function getAllowedAnswers(): ?array |
|
{ |
|
return $this->allowedAnswers; |
|
} |
|
|
|
public function setAllowedAnswers(array $allowedAnswers): self |
|
{ |
|
if (!count($allowedAnswers)) { |
|
$this->allowedAnswers = ['yes']; |
|
} else { |
|
$this->allowedAnswers = $allowedAnswers; |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function getVotesAllowed(): ?bool |
|
{ |
|
return $this->votesAllowed; |
|
} |
|
|
|
public function setVotesAllowed(?bool $votesAllowed): self |
|
{ |
|
$this->votesAllowed = $votesAllowed; |
|
|
|
return $this; |
|
} |
|
|
|
public function getModificationPolicy(): ?string |
|
{ |
|
return $this->modificationPolicy; |
|
} |
|
|
|
public function setModificationPolicy(string $modificationPolicy): self |
|
{ |
|
$this->modificationPolicy = $modificationPolicy; |
|
|
|
return $this; |
|
} |
|
|
|
public function getHideResults(): ?bool |
|
{ |
|
return $this->hideResults; |
|
} |
|
|
|
public function setHideResults(bool $hideResults): self |
|
{ |
|
$this->hideResults = $hideResults; |
|
|
|
return $this; |
|
} |
|
|
|
public function getShowResultEvenIfPasswords(): ?bool |
|
{ |
|
return $this->showResultEvenIfPasswords; |
|
} |
|
|
|
public function setShowResultEvenIfPasswords(bool $showResultEvenIfPasswords): self |
|
{ |
|
$this->showResultEvenIfPasswords = $showResultEvenIfPasswords; |
|
|
|
return $this; |
|
} |
|
|
|
public function getOwner(): ?Owner |
|
{ |
|
return $this->owner; |
|
} |
|
|
|
public function setOwner(?Owner $owner): self |
|
{ |
|
$this->owner = $owner; |
|
|
|
return $this; |
|
} |
|
|
|
public function getPassword(): ?string |
|
{ |
|
return $this->password; |
|
} |
|
|
|
public function setPassword(string $password): self |
|
{ |
|
$this->password = md5($password); |
|
|
|
return $this; |
|
} |
|
|
|
public function getAdminKey(): ?string |
|
{ |
|
return $this->adminKey; |
|
} |
|
|
|
public function setAdminKey(string $adminKey): self |
|
{ |
|
$this->adminKey = $adminKey; |
|
|
|
return $this; |
|
} |
|
|
|
public function getId(): ?int |
|
{ |
|
return $this->id; |
|
} |
|
|
|
public function findChoiceById(int $id) |
|
{ |
|
|
|
$choices = $this->getChoices(); |
|
$counter = 0; |
|
// there must be something cleaner than this in Doctrine ArrayCollection |
|
foreach ($choices as $choice) { |
|
$counter++; |
|
if ($counter > $this->maxChoicesLimit) { |
|
throw new ErrorException("max number of choices reached for this poll"); |
|
} |
|
if ($choice && $choice->getId() == $id) { |
|
return $choice; |
|
} |
|
|
|
} |
|
|
|
return null; |
|
} |
|
|
|
/** |
|
* @return Collection|Vote[] |
|
*/ |
|
public function getVotes(): Collection |
|
{ |
|
return $this->votes; |
|
} |
|
|
|
public function getCustomUrl(): ?string |
|
{ |
|
return $this->customUrl; |
|
} |
|
|
|
public function setCustomUrl(string $customUrl): self |
|
{ |
|
$this->customUrl = $customUrl; |
|
|
|
return $this; |
|
} |
|
|
|
public function getMailOnComment(): ?bool |
|
{ |
|
return $this->mailOnComment; |
|
} |
|
|
|
public function setMailOnComment(bool $mailOnComment): self |
|
{ |
|
$this->mailOnComment = $mailOnComment; |
|
|
|
return $this; |
|
} |
|
|
|
public function getMailOnVote(): ?bool |
|
{ |
|
return $this->mailOnVote; |
|
} |
|
|
|
public function setMailOnVote(bool $mailOnVote): self |
|
{ |
|
$this->mailOnVote = $mailOnVote; |
|
|
|
return $this; |
|
} |
|
|
|
public function addComment(Comment $comment): self |
|
{ |
|
if (!$this->comments->contains($comment)) { |
|
$this->comments[] = $comment; |
|
$comment->setPoll($this); |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function removeComment(Comment $comment): self |
|
{ |
|
if ($this->comments->contains($comment)) { |
|
$this->comments->removeElement($comment); |
|
// set the owning side to null (unless already changed) |
|
if ($comment->getPoll() === $this) { |
|
$comment->setPoll(null); |
|
} |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function addStackOfVote(StackOfVotes $stackOfVote): self |
|
{ |
|
if (!$this->stacksOfVotes->contains($stackOfVote)) { |
|
$this->stacksOfVotes[] = $stackOfVote; |
|
$stackOfVote->setPoll($this); |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function removeStackOfVote(StackOfVotes $stackOfVote): self |
|
{ |
|
if ($this->stacksOfVotes->contains($stackOfVote)) { |
|
$this->stacksOfVotes->removeElement($stackOfVote); |
|
// set the owning side to null (unless already changed) |
|
if ($stackOfVote->getPoll() === $this) { |
|
$stackOfVote->setPoll(null); |
|
} |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function addVote(Vote $vote): self |
|
{ |
|
if (!$this->votes->contains($vote)) { |
|
$this->votes[] = $vote; |
|
$vote->setPoll($this); |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function removeVote(Vote $vote): self |
|
{ |
|
if ($this->votes->contains($vote)) { |
|
$this->votes->removeElement($vote); |
|
// set the owning side to null (unless already changed) |
|
if ($vote->getPoll() === $this) { |
|
$vote->setPoll(null); |
|
} |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function addTextChoiceArray(array $choiceTextArray): self |
|
{ |
|
foreach ($choiceTextArray as $text) { |
|
$newChoice = new Choice(); |
|
$newChoice->setName($text); |
|
$this->addChoice($newChoice); |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function addChoice(Choice $choice): self |
|
{ |
|
if (!is_null($this->choices)) { |
|
if (!$this->choices->contains($choice)) { |
|
$this->choices[] = $choice; |
|
$choice->setPoll($this); |
|
} |
|
} else { |
|
$this->choices[] = $choice; |
|
$choice->setPoll($this); |
|
} |
|
|
|
|
|
return $this; |
|
} |
|
|
|
public function addStacksOfVote(StackOfVotes $stacksOfVote): self |
|
{ |
|
if (!$this->stacksOfVotes->contains($stacksOfVote)) { |
|
$this->stacksOfVotes[] = $stacksOfVote; |
|
$stacksOfVote->setPoll($this); |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function removeStacksOfVote(StackOfVotes $stacksOfVote): self |
|
{ |
|
if ($this->stacksOfVotes->contains($stacksOfVote)) { |
|
$this->stacksOfVotes->removeElement($stacksOfVote); |
|
// set the owning side to null (unless already changed) |
|
if ($stacksOfVote->getPoll() === $this) { |
|
$stacksOfVote->setPoll(null); |
|
} |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function removeChoice(Choice $choice): self |
|
{ |
|
if ($this->choices->contains($choice)) { |
|
$this->choices->removeElement($choice); |
|
// set the owning side to null (unless already changed) |
|
if ($choice->getPoll() === $this) { |
|
$choice->setPoll(null); |
|
} |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
public function getCommentsAllowed(): ?bool |
|
{ |
|
return $this->commentsAllowed; |
|
} |
|
|
|
public function setCommentsAllowed(?bool $commentsAllowed): self |
|
{ |
|
$this->commentsAllowed = $commentsAllowed; |
|
|
|
return $this; |
|
} |
|
|
|
public function getIsZeroKnowledge(): ?bool |
|
{ |
|
return $this->isZeroKnowledge; |
|
} |
|
|
|
public function setIsZeroKnowledge(?bool $isZeroKnowledge): self |
|
{ |
|
$this->isZeroKnowledge = $isZeroKnowledge; |
|
|
|
return $this; |
|
} |
|
}
|
|
|