knowledge-8.x-1.x-dev/src/Plugin/Block/ArticleTypes.php

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

namespace Drupal\knowledge\Plugin\Block;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides the "Article Types" block.
 *
 * @Block(
 *   id = "knowledge_article_type",
 *   admin_label = @Translation("Article Types"),
 *   category = @Translation("Knowledge")
 * )
 */
class ArticleTypes extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The time service.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * The user storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $userStorage;

  /**
   * The path current service.
   *
   * @var \Drupal\Core\Path\CurrentPathStack
   */
  protected $pathCurrent;

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

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * ModerationDashboardActivity constructor.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param \Drupal\Core\Entity\EntityStorageInterface $user_storage
   *   The user storage.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer service.
   * @param \Drupal\Core\Path\CurrentPathStack $path_current
   *   The path service.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, TimeInterface $time, EntityStorageInterface $user_storage, RendererInterface $renderer, CurrentPathStack $path_current, AccountInterface $current_user) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->database = $database;
    $this->time = $time;
    $this->userStorage = $user_storage;
    $this->renderer = $renderer;
    $this->pathCurrent = $path_current;
    $this->currentUser = $current_user;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('database'),
      $container->get('datetime.time'),
      $container->get('entity_type.manager')->getStorage('user'),
      $container->get('renderer'),
      $container->get('path.current'),
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {

    $config = $this->getConfiguration();
    $hash = $config['hash'];
    $uid = $this->getUid();
    $product = $this->getProduct();

    $parameters = [];
    if ($product != 0) {
      $parameters[':product'] = $product;
    }
    if ($config['context'] != '_none') {
      $parameters[':uid'] = $uid;
    }

    $contentStateQuery = $this->contentTypeQuery();
    $states = $this->database->query($contentStateQuery, $parameters)
      ->fetchAllAssoc('type', \PDO::FETCH_ASSOC);
    sort($states);

    if (!$states) {
      return [
        '#markup' => '<p>' . $this->t('There are no knowledge articles.') . '</p>',
      ];
    }

    $data = [
      'labels' => [],
      'datasets' => [
        [
          'label' => $this->t('type'),
          'data' => [],
          'backgroundColor' => [],
        ],
      ],
    ];

    foreach ($states as $state) {
      $data['labels'][] = ucwords(str_replace('_', ' ', $state['type']));
      $data['datasets'][0]['data'][] = $state['count'] ?? 0;
      $data['datasets'][0]['backgroundColor'][] = 'rgba(' . $this->typeColorSelector($state['type']) . ' .4)';
      $data['datasets'][0]['borderColor'][] =
          'rgba(' . $this->typeColorSelector($state['type']) . ' .9)';
    }

    $build = [
      '#cache' => [
        'contexts' => [],
      ],
      '#type' => 'container',
      '#attributes' => [
        'class' => ['knowledge-article-types'],
        'id' => [$hash],
      ],
      '#attached' => [
        'library' => ['knowledge/article_types'],
        'drupalSettings' => [
          'knowledge_article_type' => [
            $hash => $data,
          ],
        ],
      ],
    ];

    $this->renderer->addCacheableDependency($build, $config);

    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);

    $config = $this->getConfiguration();

    $form['context'] = [
      '#type' => 'select',
      '#title' => $this->t('Context'),
      '#description' => $this->t('Context the report is presented.'),
      '#default_value' => $config['context'] ?? '_none',
      '#options' => [
        '_none' => $this->t('None'),
        'user' => $this->t('User'),
        'current_user' => $this->t('Current User'),
      ],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $context = $form_state->getValue('context');
    $hash = sha1(serialize([$context]));

    $this->setConfigurationValue('context', $context);
    $this->setConfigurationValue('hash', $hash);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    return Cache::mergeTags(parent::getCacheTags(), [
      'config:knowledge.settings.node_types',
    ]);
  }

  /**
   * Returns the sql query for the count of each article type.
   */
  protected function contentTypeQuery() {
    $config = $this->getConfiguration();
    $product = $this->getProduct();
    $sql = "
      SELECT type, COUNT(type) as count
      FROM {node_field_data}
      INNER JOIN {node_revision__field_product_ref} as nrfpr
        ON nrfpr.entity_id = nid
      INNER JOIN {taxonomy_term_field_data} as ttfd
        ON nrfpr.field_product_ref_target_id = tid
      WHERE type IN ('q_a', 'how_to', 'solution')
    ";

    if ($config['context'] != '_none') {
      $sql .= "
        AND uid = :uid
      ";
    }

    if ($product != 0) {
      $sql .= "
        AND tid = :product
      ";
    }

    $sql .= "GROUP BY type";

    return $sql;
  }

  /**
   * Returns the user id for the context.
   */
  protected function getUid() {

    $currentPath = $this->pathCurrent->getPath();
    $pathArray = explode('user/', $currentPath);

    if (count($pathArray) > 1) {
      $pathArray = explode('/', $pathArray[1]);
      $uid = (int) $pathArray[0];

      if (is_int($uid)) {
        return $uid;
      }
    }

    return $this->currentUser->id();
  }

  /**
   * Returns the taxonomy id for the context.
   */
  protected function getProduct() {

    $currentPath = $this->pathCurrent->getPath();
    $pathArray = explode('taxonomy/term/', $currentPath);

    if (count($pathArray) > 1) {
      $pathArray = explode('/', $pathArray[1]);
      $product = (int) $pathArray[0];

      if (is_int($product)) {
        return $product;
      }
    }

    return 0;
  }

  /**
   * Generates a random RGB color.
   */
  protected function typeColorSelector($type) {
    switch ($type) {
      case 'page':
        $color = '255, 99, 132,';
        break;

      case 'how_to':
        $color = '54, 162, 235,';
        break;

      case 'solution':
        $color = '37, 190, 136,';
        break;

      case 'q_a':
        $color = '93, 37, 190,';
        break;

      default:
        $color = '0, 0, 0,';
        break;
    }

    return $color;
  }

}

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

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