View source
<?php
namespace Drupal\advpoll\Form;
use Drupal\poll\Form\PollViewForm;
use Drupal\Core\Form\BaseFormIdInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\poll\PollInterface;
use Symfony\Component\HttpFoundation\Request;
class ApprovalPollViewForm extends PollViewForm implements BaseFormIdInterface {
protected const writeInIndex = -1;
public function getBaseFormId() {
return 'approval_poll_view_form';
}
public function getFormId() {
return 'approval_poll_view_form_' . $this->poll
->id();
}
public function buildForm(array $form, FormStateInterface $form_state, Request $request = NULL, $view_mode = 'full') {
$startTimestamp = $this
->getStartTimestamp();
if ($startTimestamp && $startTimestamp > time()) {
$date = \Drupal::service('date.formatter')
->format($startTimestamp, 'long');
$form['start_date'] = [
'#type' => 'markup',
'#markup' => $this
->t('This poll will open on @date.', [
'@date' => $date,
]),
];
return $form;
}
$form = parent::buildForm($form, $form_state, $request, $view_mode);
$form['#attributes']['class'][] = 'poll-view-form';
$form['#attributes']['class'][] = 'poll-view-form-' . $this->poll
->id();
if (isset($form['choice'])) {
$pollType = '';
if ($this->poll
->hasField('field_poll_type')) {
$pollType = $this->poll->field_poll_type->value;
}
$form['#theme'] = 'poll_vote__advanced';
if ($pollType) {
switch ($pollType) {
case 'approval':
$form['choice']['#type'] = 'checkboxes';
break;
}
}
$isMultipleChoice = $form['choice']['#type'] == 'checkboxes';
$isWriteInPoll = FALSE;
if ($this->poll
->hasField('field_writein')) {
$isWriteInPoll = $this->poll->field_writein->value;
}
if ($isWriteInPoll) {
$form['choice']['#options'][self::writeInIndex] = $this
->t('Other (Write-in)');
$writeInWrapperId = 'write-in-fieldset-wrapper-' . $this->poll
->id();
$form['write_in'] = [
'#type' => 'fieldset',
'#prefix' => '<div id="' . $writeInWrapperId . '">',
'#suffix' => '</div>',
];
if ($isMultipleChoice) {
$form['write_in']['#states']['visible']['input[name="choice[' . self::writeInIndex . ']"]']['checked'] = TRUE;
}
else {
$form['write_in']['#states']['visible']['input[name="choice"]']['value'] = self::writeInIndex;
}
$maxChoices = $this
->getMaxChoices();
$numWriteIn = $form_state
->get('num_writein');
if ($numWriteIn === NULL) {
$numWriteIn = 1;
$form_state
->set('num_writein', $numWriteIn);
}
for ($i = 0; $i < $numWriteIn; $i++) {
$form['write_in']['write_in_' . $i] = [
'#type' => 'textfield',
];
}
$allowMultipleWriteIn = FALSE;
if ($isMultipleChoice && $this->poll
->hasField('field_writein_multiple') && !$this->poll
->get('field_writein_multiple')
->isEmpty()) {
$allowMultipleWriteIn = $this->poll
->get('field_writein_multiple')->value;
}
if ($allowMultipleWriteIn && (empty($maxChoices) || $numWriteIn < $maxChoices)) {
$form['write_in']['actions'] = [
'#type' => 'actions',
];
$form['write_in']['actions']['add'] = [
'#type' => 'submit',
'#value' => $this
->t('Add'),
'#submit' => [
'::addOneWriteIn',
],
'#ajax' => [
'callback' => '::addWriteInCallback',
'wrapper' => $writeInWrapperId,
],
];
}
}
if (!empty($form['choice']['#options'])) {
$choiceKeys = array_keys($form['choice']['#options']);
$choicesWriteIn = \Drupal::entityTypeManager()
->getStorage('poll_choice')
->loadByProperties([
'id' => $choiceKeys,
'field_writein' => TRUE,
]);
if ($choicesWriteIn) {
foreach ($choicesWriteIn as $choice) {
unset($form['choice']['#options'][$choice
->id()]);
}
}
}
}
return $form;
}
public function validateVote(array &$form, FormStateInterface $form_state) {
parent::validateVote($form, $form_state);
$maxChoices = $this
->getMaxChoices();
if ($maxChoices) {
$choices = array_filter($form_state
->getValue('choice'));
$writeInOptions = [];
if (isset($choices[self::writeInIndex])) {
$writeInOptions = $this
->getWriteInOptions($form_state);
unset($choices[self::writeInIndex]);
}
if (count($choices) + count($writeInOptions) > $maxChoices) {
$form_state
->setErrorByName('choice', $this
->t('Select up to @quantity @votes.', [
'@quantity' => $maxChoices,
'@votes' => $this
->formatPlural($maxChoices, 'vote', 'votes'),
]));
}
}
}
public function showResults(PollInterface $poll, FormStateInterface $form_state) {
$showResults = parent::showResults($poll, $form_state);
if (!$showResults) {
$duration = $this->poll
->getRuntime();
if ($duration) {
$startTimestamp = $this
->getStartTimestamp();
if (empty($startTimestamp)) {
$startTimestamp = $this->poll
->getCreated();
}
if ($startTimestamp + $duration < time()) {
$showResults = TRUE;
}
}
}
return $showResults;
}
public function cancel(array $form, FormStateInterface $form_state) {
$vote_storage = \Drupal::service('poll_vote.storage');
$vote_storage
->cancelVote($this->poll, $this
->currentUser());
\Drupal::logger('poll')
->notice('%user\'s vote in Poll #%poll deleted.', array(
'%user' => $this
->currentUser()
->id(),
'%poll' => $this->poll
->id(),
));
\Drupal::messenger()
->addMessage($this
->t('Your vote was cancelled.'));
if ($this
->getRequest()->query
->get('ajax_form')) {
$form_state
->setRebuild(TRUE);
}
}
public function save(array $form, FormStateInterface $form_state) {
$choices = $form_state
->getValue('choice');
if (!is_array($choices)) {
$choices = [
$choices => $choices,
];
}
$storagePollChoice = \Drupal::entityTypeManager()
->getStorage('poll_choice');
foreach ($choices as $index => $choice) {
if ($choice) {
if ($index == self::writeInIndex) {
$writeInOptions = $this
->getWriteInOptions($form_state);
$pollOptions = $this->poll
->getOptions();
foreach ($writeInOptions as $writeInOption) {
$chId = array_search($writeInOption, $pollOptions);
if (empty($chId)) {
$pollChoice = $storagePollChoice
->create([
'choice' => $writeInOption,
]);
$pollChoice
->set('field_writein', TRUE);
$pollChoice
->save();
$this->poll
->get('choice')
->appendItem($pollChoice);
$this->poll
->save();
$chId = $pollChoice
->id();
}
$this
->saveVote($chId);
}
}
else {
$chId = $index;
$this
->saveVote($chId);
}
}
}
\Drupal::messenger()
->addMessage($this
->t('Your vote has been recorded.'));
if ($this
->currentUser()
->isAnonymous()) {
$_SESSION['poll_vote'][$form_state
->getValue('poll')
->id()] = $form_state
->getValue('choice');
}
if ($this
->getRequest()->query
->get('ajax_form')) {
$form_state
->setRebuild(TRUE);
}
}
public function addWriteInCallback(array &$form, FormStateInterface $form_state) {
return $form['write_in'];
}
public function addOneWriteIn(array &$form, FormStateInterface $form_state) {
$numWriteIn = $form_state
->get('num_writein');
$form_state
->set('num_writein', $numWriteIn + 1);
$form_state
->setRebuild();
}
protected function getMaxChoices() {
$maxChoices = 0;
if ($this->poll
->hasField('field_number_of_votes') && !$this->poll
->get('field_number_of_votes')
->isEmpty()) {
$maxChoices = $this->poll
->get('field_number_of_votes')->value;
}
return $maxChoices;
}
protected function getWriteInOptions(FormStateInterface $form_state) {
$numWriteIn = $form_state
->get('num_writein');
$writeInOptions = [];
for ($i = 0; $i < $numWriteIn; $i++) {
$value = trim($form_state
->getValue('write_in_' . $i));
if ($value) {
$writeInOptions[] = $value;
}
}
return $writeInOptions;
}
protected function getStartTimestamp() {
$startTimestamp = 0;
if ($this->poll
->hasField('field_start_date') && !$this->poll
->get('field_start_date')
->isEmpty()) {
$startDateTime = $this->poll
->get('field_start_date')->date;
$startTimestamp = $startDateTime
->getTimestamp();
}
return $startTimestamp;
}
protected function saveVote($chId) {
$options = array();
$options['chid'] = $chId;
$options['uid'] = $this
->currentUser()
->id();
$options['pid'] = $this->poll
->id();
$options['hostname'] = \Drupal::request()
->getClientIp();
$options['timestamp'] = time();
$voteStorage = \Drupal::service('poll_vote.storage');
$voteStorage
->saveVote($options);
}
}