openquestions-1.0.x-dev/src/Plugin/Block/OQScoreboardBlock.php

src/Plugin/Block/OQScoreboardBlock.php
<?php

namespace Drupal\openquestions\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\Core\Utility\LinkGeneratorInterface;
use Drupal\Core\Session\AccountProxy;
use Drupal\Component\Render\FormattableMarkup;

/**
 * OpenQuestions Scoreboard block. Designed to show the current votes on
 * OQ Item pages.
 *
 * "entity:oq_item" is available due to OQItemRouteContext.
 *
 * @Block(
 *  id = "oq_scoreboard_block",
 *  admin_label = @Translation("OQ Scoreboard"),
 *  category = @Translation("OpenQuestions"),
 *  context_definitions = {
 *    "oq_item" = @ContextDefinition("entity:oq_item", label = @Translation("OQ Item"))
 *  }
 * )
 */
class OQScoreboardBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * To generate links.
   *
   * @var \Drupal\Core\Utility\LinkGeneratorInterface
   */
  protected $linkGenerator;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountProxy
   */
  protected $currentUser;

  /**
   * Our logger.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $logger;

  /**
   * Constructs an OQScoreboardBlock.
   */
  public function __construct(array $configuration,
                  $plugin_id,
                  $plugin_definition,
                  LinkGeneratorInterface $linkGenerator,
                  AccountProxy $currentUser,
                  LoggerChannelInterface $logger) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->linkGenerator = $linkGenerator;
    $this->currentUser = $currentUser;
    $this->logger = $logger;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('link_generator'),
      $container->get('current_user'),
      $container->get('openquestions.logger.channel.openquestions')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'expand_all' => 1,
      'expand_questions' => 1,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form['expand_all'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Expand all'),
      '#description' => $this->t('Expand all'),
      '#default_value' => $this->configuration['expand_all'],
    ];

    $form['expand_questions'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Expand questions'),
      '#description' => $this->t('Expand questions'),
      '#default_value' => $this->configuration['expand_questions'],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $this->configuration['expand_all'] = $form_state->getValue('expand_all');
    $this->configuration['expand_questions'] = $form_state->getValue('expand_questions');
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $item = $this->getContextValue('oq_item');
    $voteData = $item->getVoteData();
    $accounts = $voteData->getAccountsThatAreAllowedToVoteOnThisItem();

    $ret = [];

    $questions = $item->getQuestions();
    foreach ($questions as $question) {
      if ($question->get('status')->value) {
        $ret[] = $this->buildQuestion($question, $voteData, $accounts);
        $ret[] = $this->buildQuestionFooter($question, $voteData, $accounts);
      }
    }

    $ret['#attached']['library'][] = 'openquestions/openquestions_voting';

    return $ret;
  }

  /**
   * Build a virtual table for the given question.
   */
  protected function buildQuestion($question, $voteData, $accounts) {
    $ret = [
      '#theme' => 'table__openquestions_voting',
      '#caption' => '',
      '#question_id' => 0,
      '#current_uid' => 0,
      '#accounts' => [],
      '#votes' => [],
    ];

    $ret['#caption'] = $question->get('label')->value;
    $ret['#question_id'] = $questionID = $question->id();
    $ret['#current_uid'] = $currentUID = $this->currentUser->id();

    foreach ($accounts as $account) {
      $ret['#accounts'][] = [
        'uid' => $account->id(),
        'name' => $account->get('name')->value,
        'url' => $account->toUrl()->toString(),
      ];
    }

    $itemID = $this->getContextValue('oq_item')->id();

    foreach ($accounts as $account) {
      $ary = $voteData->getVotesForQuestionIdAndAccountId($questionID, $account->id());
      $vote = $ary ? array_shift($ary) : NULL;
      $row = [
        'type' => NULL,
        'value' => NULL,
        'vote_url' => NULL,
        'uid' => $account->id(),
        'item_id' => $itemID,
        'question_id' => $questionID,
      ];

      if (!$vote) {
        if ($currentUID && $currentUID == $account->id()) {
          $row['type'] = 'voteable';
          $row['value'] = $this->t('Vote');
        }
        else {
          $row['type'] = 'empty';
          $row['value'] = '--';
        }
      }
      else {
        $row['vote_url'] = $vote->toUrl()->toString();
        $row['value'] = $question->getOptionName($vote->get('vote_value')->value);

        if (!$vote->get('status')->value) {
          $row['type'] = 'canceled';
          $row['value'] .= ' ' . $this->t('(X)');
        }
        else {
          $row['type'] = 'voted';
        }
      }

      $ret['#votes'][] = $row;
    }

    return $ret;
  }

  /**
   * Build the info for the footer of a question table.
   */
  protected function buildQuestionFooter($question, $voteData, $accounts) {
    $ret = [
      '#type' => 'item',
      '#markup' => '',
    ];

    $rangeInfo = $question->getOptionsRangeInfo();

    if ($rangeInfo['type'] == 'binary') {
      $ret['#markup'] = $this->t('Choices are @a or @b', ['@a' => $rangeInfo['first'], '@b' => $rangeInfo['last']]);
    }
    else {
      $ret['#markup'] = $this->t('Choices range between @a and @b', ['@a' => $rangeInfo['first'], '@b' => $rangeInfo['last']]);
    }

    return $ret;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc