registerLink($this->getElection()); $vote->notUpdate = true; $this->getElection()->checkVoteCandidate($vote); $vote->notUpdate = false; return $vote; } protected function encodeOneEntity(Vote $data): string { $data->destroyLink($this->getElection()); return str_replace([' > ', ' = '], ['>', '='], (string) $data); } protected function preDeletedTask(Vote $object): void { $object->destroyLink($this->getElection()); } /////////// Array Access - Specials improvements /////////// public function offsetGet(mixed $offset): Vote { return parent::offsetGet($offset); } #[Throws(VoteManagerException::class)] public function offsetSet(mixed $offset, mixed $value): void { if ($value instanceof Vote) { parent::offsetSet((\is_int($offset) ? $offset : null), $value); $this->UpdateAndResetComputing(key: $this->maxKey, type: 1); } else { throw new VoteManagerException; } $this->checkRegularize(); } public function offsetUnset(mixed $offset): void { $this->UpdateAndResetComputing(key: $offset, type: 2); parent::offsetUnset($offset); } /////////// Internal Election related methods /////////// public function UpdateAndResetComputing(int $key, int $type): void { $election = $this->getElection(); if ($election->getState() === ElectionState::VOTES_REGISTRATION) { if ($type === 1) { $election->getPairwise()->addNewVote($key); } elseif ($type === 2) { $election->getPairwise()->removeVote($key); } $election->cleanupCalculator(); } else { $election->setStateToVote(); } } /////////// Get Votes Methods /////////// public function getVoteKey(Vote $vote): ?int { ($r = array_search(needle: $vote, haystack: $this->Container, strict: true)) !== false || ($r = array_search(needle: $vote, haystack: $this->Cache, strict: true)); return ($r !== false) ? $r : null; } protected function getFullVotesListGenerator(): \Generator { foreach ($this as $voteKey => $vote) { yield $voteKey => $vote; } } protected function getPartialVotesListGenerator(array $tags, bool $with): \Generator { foreach ($this as $voteKey => $vote) { $noOne = true; foreach ($tags as $oneTag) { if (($oneTag === $voteKey) || \in_array(needle: $oneTag, haystack: $vote->getTags(), strict: true)) { if ($with) { yield $voteKey => $vote; break; } else { $noOne = false; } } } if (!$with && $noOne) { yield $voteKey => $vote; } } } // Get the votes list public function getVotesList(?array $tags = null, bool $with = true): array { if ($tags === null) { return $this->getFullDataSet(); } else { $search = []; foreach ($this->getPartialVotesListGenerator($tags, $with) as $voteKey => $vote) { $search[$voteKey] = $vote; } return $search; } } // Get the votes list as a generator object public function getVotesListGenerator(?array $tags = null, bool $with = true): \Generator { if ($tags === null) { return $this->getFullVotesListGenerator(); } else { return $this->getPartialVotesListGenerator($tags, $with); } } public function getVotesValidUnderConstraintGenerator(?array $tags = null, bool $with = true): \Generator { $election = $this->getElection(); $generator = ($tags === null) ? $this->getFullVotesListGenerator() : $this->getPartialVotesListGenerator($tags, $with); foreach ($generator as $voteKey => $oneVote) { if (!$election->testIfVoteIsValidUnderElectionConstraints($oneVote)) { continue; } yield $voteKey => $oneVote; } } public function getVotesListAsString(bool $withContext): string { $election = $this->getElection(); $simpleList = ''; $weight = []; $nb = []; foreach ($this as $oneVote) { $oneVoteString = $oneVote->getSimpleRanking($withContext ? $election : null); if (!\array_key_exists(key: $oneVoteString, array: $weight)) { $weight[$oneVoteString] = 0; } if (!\array_key_exists(key: $oneVoteString, array: $nb)) { $nb[$oneVoteString] = 0; } if ($election->isVoteWeightAllowed()) { $weight[$oneVoteString] += $oneVote->getWeight(); } else { $weight[$oneVoteString]++; } $nb[$oneVoteString]++; } ksort($weight, \SORT_NATURAL); arsort($weight); $isFirst = true; foreach ($weight as $key => $value) { if (!$isFirst) { $simpleList .= "\n"; } $voteString = ($key === '') ? CondorcetElectionFormat::SPECIAL_KEYWORD_EMPTY_RANKING : $key; $simpleList .= $voteString.' * '.$nb[$key]; $isFirst = false; } return $simpleList; } public function countVotes(?array $tag, bool $with): int { if ($tag === null) { return \count($this); } else { $count = 0; foreach ($this as $key => $value) { $noOne = true; foreach ($tag as $oneTag) { if (($oneTag === $key) || \in_array(needle: $oneTag, haystack: $value->getTags(), strict: true)) { if ($with) { $count++; break; } else { $noOne = false; } } } if (!$with && $noOne) { $count++; } } return $count; } } public function countInvalidVoteWithConstraints(): int { $election = $this->getElection(); $count = 0; foreach ($this as $oneVote) { if (!$election->testIfVoteIsValidUnderElectionConstraints($oneVote)) { $count++; } } return $count; } public function sumVotesWeight(bool $constraint = false): int { $election = $this->getElection(); $sum = 0; foreach ($this as $oneVote) { if (!$constraint || $election->testIfVoteIsValidUnderElectionConstraints($oneVote)) { $sum += $election->isVoteWeightAllowed() ? $oneVote->getWeight() : 1; } } return $sum; } }