work_time-1.0.x-dev/src/Plugin/Block/WorkTimerBlock.php

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

namespace Drupal\work_time\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\TitleResolverInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Provides a Work time block.
 *
 * @Block(
 *   id = "work_time_block",
 *   admin_label = @Translation("Work time"),
 *   category = @Translation("Work time")
 * )
 */
class WorkTimerBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * Current quest service.
   *
   * @var \Drupal\Core\Http\RequestStack
   */
  protected $requestStack;

  /**
   * Config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Entity field mananger.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * Route match service.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * Title resolver service.
   *
   * @var \Drupal\Core\Controller\TitleResolverInterface
   */
  protected $titleResolver;

  /**
   * The entity type bundle information.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
   */
  protected $entityTypeBundleInfo;

  /**
   * Constructs a Drupalist object.
   *
   * @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\Config\ConfigFactoryInterface $config_factory
   *   The config factory service.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request service.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The field manager service.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match service.
   * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
   *   The title resolver service.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle information.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, RequestStack $request_stack, EntityFieldManagerInterface $entity_field_manager, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver, EntityTypeBundleInfoInterface $entity_type_bundle_info) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->requestStack = $request_stack;
    $this->configFactory = $config_factory;
    $this->entityFieldManager = $entity_field_manager;
    $this->routeMatch = $route_match;
    $this->titleResolver = $title_resolver;
    $this->entityTypeBundleInfo = $entity_type_bundle_info;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('config.factory'),
      $container->get('request_stack'),
      $container->get('entity_field.manager'),
      $container->get('current_route_match'),
      $container->get('title_resolver'),
      $container->get('entity_type.bundle.info'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'entity_type' => 'node',
      'entity_bundle' => 'user',
      'entity_field' => '',
      'reference_field' => '',
      'reference_type' => '',
      'url_projects' => '',
      'limit' => 'week',
    ];
  }

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

    // Build a wrapper for the ajax response.
    $form['collect_field_label'] = [
      '#type' => 'container',
      '#attributes' => [
        'id' => $this->getFormId(),
      ],
    ];
    $settings = $this->requestStack->getCurrentRequest()->get('settings');
    $type = $this->configuration['entity_type'];
    $bundle = $this->configuration['entity_bundle'];
    $reference_field = $this->configuration['reference_field'];
    $reference_type = $this->configuration['reference_type'];
    $entity_field = $this->configuration['entity_field'];
    $limit = $this->configuration['limit'];
    if (!empty($settings["collect_field_label"])) {
      if (!empty($settings["collect_field_label"]["entity_type"])) {
        $type = $settings["collect_field_label"]["entity_type"];
      }
      if (!empty($settings["collect_field_label"]["entity_bundle"])) {
        $bundle = $settings["collect_field_label"]["entity_bundle"];
      }
    }

    $form['collect_field_label']['entity_type'] = [
      '#type' => 'select',
      '#title' => $this->t('Type'),
      '#required' => TRUE,
      '#description' => $this->t('Set your task entity'),
      "#empty_option" => $this->t('- Select -'),
      '#default_value' => $type,
      '#options' => [
        'node' => $this->t('Node'),
        'taxonomy_term' => $this->t('Taxonomy'),
        'user' => $this->t('User'),
      ],
      '#weight' => 0,
      '#ajax' => [
        'callback' => [$this, 'ajaxCollectFieldCallback'],
        'wrapper' => $this->getFormId(),
        'event' => 'change',
        'options' => ['query' => ['ajax_form' => 1]],
        'progress' => [
          'type' => 'throbber',
          'message' => $this->t('Verifying entry...'),
        ],
      ],
    ];
    $option_bundle = $this->collectBundleLabelType($type) ?? [];
    $form['collect_field_label']['entity_bundle'] = [
      '#type' => 'select',
      '#title' => $this->t('Bundle'),
      '#description' => $this->t('which task bundle'),
      "#empty_option" => $this->t('- Select -'),
      '#options' => $option_bundle,
      '#default_value' => $bundle,
      '#ajax' => [
        'callback' => [$this, 'ajaxCollectFieldCallback'],
        'wrapper' => $this->getFormId(),
        'event' => 'change',
        'options' => ['query' => ['ajax_form' => 1]],
        'progress' => [
          'type' => 'throbber',
          'message' => $this->t('Verifying entry...'),
        ],
      ],
    ];

    $optionFieldDaterange = $this->collectFieldLabelType($type, $bundle, 'daterange') ?? [];
    $form['collect_field_label']['entity_field'] = [
      '#type' => 'select',
      '#title' => $this->t('Field to store date and time'),
      '#description' => $this->t('Daterange field'),
      "#empty_option" => $this->t('- Select -'),
      '#options' => $optionFieldDaterange,
      '#default_value' => $entity_field,
    ];

    $optionFieldReference = $this->collectFieldLabelType($type, $bundle, 'entity_reference') ?? [];
    $form['collect_field_label']['reference_field'] = [
      '#type' => 'select',
      '#title' => $this->t('Project field'),
      '#description' => $this->t('Reference field to store entity project'),
      "#empty_option" => $this->t('- Select -'),
      '#options' => $optionFieldReference,
      '#default_value' => $reference_field,
    ];
    $form['collect_field_label']['reference_type'] = $form['collect_field_label']['entity_type'];
    $form['collect_field_label']['reference_type']['#default_value'] = $reference_type;
    $form['collect_field_label']['reference_type']['#title'] = $this->t('Project Type');
    $form['collect_field_label']['limit'] = [
      '#type' => 'select',
      '#title' => $this->t('History limit'),
      '#description' => $this->t('Show history timer in week or month'),
      "#empty_option" => $this->t('- Select -'),
      '#options' => ['week' => $this->t('Week'), 'month' => $this->t('Month')],
      '#default_value' => $limit,
    ];
    $form['collect_field_label']['url_projects'] = [
      '#type' => 'textfield',
      '#title' => $this->t('REST export path for project list'),
      '#description' => $this->t('Use views REST export to get list project format [{"title":"Project 1","nid":"2"},{"title":"Test Project 2","nid":"3"}]'),
      '#default_value' => $this->configuration['url_projects'],
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $config = $this->getConfiguration();
    $reference_id = $entity_id = '';
    $entity_type = $config['entity_type'];
    $entity_bundle = $config['entity_bundle'];
    $entity_field = $config['entity_field'];
    $reference_field = $config['reference_field'];
    $reference_type = $config['reference_type'];
    $request = $this->requestStack->getCurrentRequest();
    $route = $this->routeMatch->getCurrentRouteMatch()->getRouteObject();
    $label = $this->titleResolver->getTitle($request, $route);
    if (empty($label)) {
      $label = $route->getDefault('_title');
    }

    $parameters = $this->routeMatch->getParameters();
    foreach ($parameters as $entity) {
      if ($entity instanceof EntityInterface) {
        $entity_id = $entity->id();
        if (!is_numeric($entity_id)) {
          break;
        }
        $entity_type = $entity->getEntityTypeId();
        switch ($entity_type) {
          case 'user':
            $entity_bundle = $entity->bundle();
            $label = $entity->getDisplayName();
            break;

          case 'taxonomy_term':
            $entity_bundle = $entity->bundle();
            $label = $entity->getName();
            break;

          case 'work_time':
            $entity_bundle = $entity->bundle();
            $label = $entity->get('label')->value;
            break;

          default:
            $entity_bundle = method_exists($entity, 'getType') ? $entity->getType() : $entity_type;
            $label = method_exists($entity, 'getTitle') ? $entity->getTitle() : '';
        }
        if (!empty($reference_field)) {
          $field_storage = FieldStorageConfig::loadByName($entity_type, $reference_field);
          if (!empty($field_storage) && in_array($entity_bundle, $field_storage->getBundles())) {
            $reference_id = $entity->get($reference_field)->target_id;
          }
        }
        break;
      }
    }
    $build = [
      '#theme' => 'work_time_block',
      '#entity_id' => $entity_id,
      '#entity_type' => $entity_type,
      '#entity_bundle' => $entity_bundle,
      '#entity_field' => $entity_field,
      '#reference_id' => $reference_id,
      '#reference_field' => $reference_field,
      '#reference_type' => $reference_type,
      '#limit' => $config['limit'],
      '#label' => $label,
      '#url_projects' => $config['url_projects'],
      '#attached' => [
        'drupalSettings' => ['work_time_block' => $config],
        'library' => ['work_time/work-time-block'],
      ],
      '#cache' => [
        'max-age' => 0,
      ],
    ];
    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    return 0;
  }

  /**
   * {@inheritdoc}
   */
  private function getFormId() {
    return 'work_time_block';
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $values = $form_state->getValues();
    $this->configuration['entity_type'] = $values["collect_field_label"]["entity_type"];
    $this->configuration['entity_bundle'] = $values["collect_field_label"]['entity_bundle'];
    $this->configuration['entity_field'] = $values["collect_field_label"]['entity_field'];
    $this->configuration['reference_field'] = $values["collect_field_label"]['reference_field'];
    $this->configuration['reference_type'] = $values["collect_field_label"]['reference_type'];
    $this->configuration['limit'] = $values["collect_field_label"]['limit'];
    $this->configuration['url_projects'] = $values["collect_field_label"]['url_projects'];
  }

  /**
   * {@inheritdoc}
   */
  private function collectBundleLabelType($type = FALSE) {
    $bundles = [];
    if (!empty($type)) {
      if (!in_array($type, ['user'])) {
        $entity_types = $this->entityTypeBundleInfo->getBundleInfo($type);
        if (!empty($entity_types)) {
          foreach ($entity_types as $key => $name) {
            $bundles[$key] = !empty($name['label']) ? (string) $name['label'] : NULL;
          }
        }
      }
    }
    return $bundles;
  }

  /**
   * {@inheritdoc}
   */
  public function ajaxCollectFieldCallback(array &$form, FormStateInterface $form_state) {
    $selectedType = $form_state->getValue('settings');
    if (!empty($form["settings"]['collect_field_label']['entity_bundle']) && !empty($selectedType["collect_field_label"]["entity_type"])) {
      $options = [
        $form["settings"]['collect_field_label']['entity_bundle']['#empty_value'] => $form["settings"]['collect_field_label']['entity_bundle']['#empty_option'],
      ] +
      $this->collectBundleLabelType($selectedType["collect_field_label"]["entity_type"]);
      if (!empty($options)) {
        $form["settings"]['collect_field_label']['bundle']['#options'] = $options;
      }
    }
    return $form["settings"]['collect_field_label'];
  }

  /**
   * {@inheritdoc}
   */
  private function collectFieldLabelType($entity_type = '', $bundle = '', $fieldType = '') {
    if ($entity_type == "user") {
      $bundle = 'user';
    }
    if (empty($entity_type) || empty($bundle)) {
      return NULL;
    }
    $infos = [];
    $fields = $this->entityFieldManager->getFieldDefinitions($entity_type, $bundle);
    $typeExcept = ['feeds_item', 'entity_reference_revisions', 'comment'];
    foreach ($fields as $field_name => $field_definition) {
      if ($field_definition instanceof FieldConfig) {
        $type = $field_definition->getType();
        if (!empty($fieldType)) {
          if ($type == $fieldType) {
            $infos[$field_name] = $field_definition->getLabel();
          }
        }
        elseif (!in_array($type, $typeExcept)) {
          $infos[$field_name] = $field_definition->getLabel();
        }
      }
    }
    return $infos;
  }

}

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

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