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

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

namespace Drupal\knowledge\Plugin\Block;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Block\BlockBase;
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 "Knowledge Activity" block.
 *
 * @Block(
 *   id = "knowledge_activity",
 *   admin_label = @Translation("Knowledge Activity"),
 *   category = @Translation("Knowledge")
 * )
 */
class KnowledgeActivity 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;

  /**
   * Knowledge Activity 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();
    $request_time = $this->time->getCurrentTime();

    $items = $config['items'] ?? 10;
    $parameters = [];
    switch ($config['frequency']) {
      case 'day':
        $parameters[':format'] = "'%Y-%m-%d'";
        $request_time_sub_month = strtotime('-1 day', $request_time);
        $request_time_sub_month_end = strtotime("-$items day", $request_time_sub_month);
        $max_age = 28800;
        break;

      case 'week':
        $parameters[':format'] = "'%Y-%V'";
        $request_time_sub_month = strtotime('-1 week', $request_time);
        $request_time_sub_month = strtotime('last day of this week', $request_time_sub_month);
        $request_time_sub_month_end = strtotime("-$items week", $request_time_sub_month);
        $max_age = 86400;
        break;

      case 'month':
      default:
        $parameters[':format'] = "'%Y-%m'";
        $request_time_sub_month = strtotime('-1 month', $request_time);
        $request_time_sub_month = strtotime('last day of this month', $request_time_sub_month);
        $request_time_sub_month_end = strtotime("-$items month", $request_time_sub_month);
        $max_age = 86400 * 2;
        break;
    }
    $parameters[':end_date'] = $request_time_sub_month;
    $parameters[':start_date'] = $request_time_sub_month_end;
    if ($config['context'] != '_none') {
      $parameters[':uid'] = $uid;
    }
    $linkedContentQuery = $this->contentLinkedQuery();
    $results2 = $this->database->query($linkedContentQuery, $parameters)
      ->fetchAllAssoc('date', \PDO::FETCH_ASSOC);

    $createdContentQuery = $this->contentCreatedQuery();
    $results1 = $this->database->query($createdContentQuery, $parameters)
      ->fetchAllAssoc('date', \PDO::FETCH_ASSOC);

    $dates = array_merge(array_keys($results1), array_keys($results2));
    $dates = array_unique($dates);
    sort($dates);

    if (!$dates) {
      return [
        '#markup' => '<p>' . $this->t('There has been no knowledge activity.') . '</p>',
      ];
    }

    $data = [
      'labels' => [],
      'datasets' => [
        [
          'label' => $this->t('Content created'),
          'data' => [],
          'backgroundColor' => [],
        ],
        [
          'label' => $this->t('Content Linked'),
          'data' => [],
          'backgroundColor' => [],
        ],
      ],
    ];
    foreach ($dates as $date) {
      $data['labels'][] = $date;
      $data['datasets'][0]['data'][] = $results1[$date]['count'] ?? 0;
      $data['datasets'][0]['backgroundColor'][] = 'rgba(54, 162, 235,.4)';
      $data['datasets'][0]['borderColor'][] = 'rgba(54, 162, 235,.9)';
      $data['datasets'][1]['data'][] = $results2[$date]['count'] ?? 0;
      $data['datasets'][1]['backgroundColor'][] = 'rgba(255, 99, 132,.4)';
      $data['datasets'][1]['borderColor'][] = 'rgba(255, 99, 132,.9)';
    }

    $build = [
      '#cache' => [
        'contexts' => [],
        'max-age' => $max_age,
      ],
      '#type' => 'container',
      '#attributes' => [
        'class' => ['knowledge-activity'],
        'id' => [$hash],
      ],
      '#attached' => [
        'library' => ['knowledge/activity'],
        'drupalSettings' => [
          'knowledge_activity' => [
            $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'),
      ],
    ];

    $form['frequency'] = [
      '#type' => 'select',
      '#title' => $this->t('Frequency'),
      '#description' => $this->t('Time period.'),
      '#default_value' => $config['frequency'] ?? 'month',
      '#options' => [
        'day' => $this->t('Daily'),
        'week' => $this->t('Weekly'),
        'month' => $this->t('Monthly'),
      ],
    ];

    $form['items'] = [
      '#type' => 'number',
      '#title' => $this->t('Items'),
      '#description' => $this->t('Time period.'),
      '#default_value' => $config['items'] ?? 6,
    ];

    return $form;
  }

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

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

  /**
   * Returns the sql query for content created by user.
   */
  protected function contentCreatedQuery() {
    $config = $this->getConfiguration();
    $sql = "
    SELECT COUNT(*) as count, DATE_FORMAT(FROM_UNIXTIME(created), :format) as date
      FROM {node_revision} AS nr
        INNER JOIN {node_field_data} AS nfd
          ON nr.nid = nfd.nid

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

    $sql .= "
        AND created BETWEEN :start_date AND :end_date
        AND created = revision_timestamp
      GROUP BY DATE_FORMAT(FROM_UNIXTIME(created), :format)
      ORDER BY DATE_FORMAT(FROM_UNIXTIME(created), :format)

    ";

    return $sql;
  }

  /**
   * Returns the sql query for content created by user.
   */
  protected function contentLinkedQuery() {
    $config = $this->getConfiguration();
    $sql = "
    SELECT COUNT(*) as count, DATE_FORMAT(FROM_UNIXTIME(k.created), :format) as date
      FROM {knowledge} as k
      INNER JOIN {node_field_data} as nfd on k.entity_id = nid

      WHERE type IN ('q_a', 'how_to', 'solution')
      AND k.entity_type = 'node'
      ";
    if ($config['context'] != '_none') {
      $sql .= "
        AND k.uid = :uid
      ";
    }

    $sql .= "
        AND k.created BETWEEN :start_date AND :end_date
      GROUP BY DATE_FORMAT(FROM_UNIXTIME(k.created), :format)
      ORDER BY DATE_FORMAT(FROM_UNIXTIME(k.created), :format)
    ";

    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();
  }

}

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

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