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