knowledge-8.x-1.x-dev/modules/knowledge_field/src/Plugin/Field/FieldWidget/KnowledgeCompetencyRoleWidget.php
modules/knowledge_field/src/Plugin/Field/FieldWidget/KnowledgeCompetencyRoleWidget.php
<?php
declare(strict_types=1);
namespace Drupal\knowledge_field\Plugin\Field\FieldWidget;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\knowledge\KnowledgeCompetencyInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Defines the 'knowledge_competency_role' field widget.
*
* @FieldWidget(
* id = "knowledge_competency_role",
* label = @Translation("Competency Role"),
* field_types = {"knowledge_competency_role"},
* )
*/
final class KnowledgeCompetencyRoleWidget extends WidgetBase {
/**
* The field definitions.
*
* @var array
*/
protected $fieldDefinitions;
/**
* The competency settings.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected $competencySettings;
/**
* The user storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $userStorage;
/**
* The event dispatcher.
*
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* Constructs a Competency Role widget.
*
* @param string $plugin_id
* The plugin_id for the widget.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The definition of the field to which the widget is associated.
* @param array $settings
* The widget settings.
* @param array $third_party_settings
* Any third party settings.
* @param array $fields_definitions
* The field definitions.
* @param \Drupal\Core\Config\ImmutableConfig $competency_settings
* The settings.
* @param \Drupal\Core\Entity\EntityStorageInterface $user_storage
* The user storage.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, array $fields_definitions, ImmutableConfig $competency_settings, EntityStorageInterface $user_storage, EventDispatcherInterface $event_dispatcher) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
$this->fieldDefinitions = $fields_definitions;
$this->competencySettings = $competency_settings;
$this->userStorage = $user_storage;
$this->eventDispatcher = $event_dispatcher;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['third_party_settings'],
$container->get('entity_field.manager')->getFieldDefinitions('knowledge_competency', 'knowledge_competency'),
$container->get('config.factory')->get('knowledge.competency.settings'),
$container->get('entity_type.manager')->getStorage('user'),
$container->get('event_dispatcher')
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings(): array {
$setting = ['foo' => 'bar'];
return $setting + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state): array {
$element['foo'] = [
'#type' => 'textfield',
'#title' => $this->t('Foo'),
'#default_value' => $this->getSetting('foo'),
];
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsSummary(): array {
return [
$this->t('Foo: @foo', ['@foo' => $this->getSetting('foo')]),
];
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state): array {
$element['role'] = [
'#type' => 'textfield',
'#title' => $this->t('Role'),
'#default_value' => $items[$delta]->role ?? NULL,
];
$element['correct'] = [
'#type' => 'textfield',
'#title' => $this->t('Correct'),
'#default_value' => $items[$delta]->correct ?? NULL,
];
$element['total'] = [
'#type' => 'textfield',
'#title' => $this->t('Total'),
'#default_value' => $items[$delta]->total ?? NULL,
];
$coach = NULL;
if ($items[$delta]->coach) {
$coach = $this->userStorage->load($items[$delta]->coach);
}
$element['proposer'] = [
'#type' => 'entity_autocomplete',
'#title' => $this->t('Coach'),
'#target_type' => 'user',
'#default_value' => $coach,
];
$approver = NULL;
if ($items[$delta]->approver) {
$approver = $this->userStorage->load($items[$delta]->approver);
}
$element['approver'] = [
'#type' => 'entity_autocomplete',
'#title' => $this->t('Approver'),
'#target_type' => 'user',
'#default_value' => $approver,
];
return $element;
}
/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state): array {
$form_values = $form_state->getValues();
$entity = $form_state->getFormObject()->getEntity();
$existing_values = $this->getExistingValues($entity);
$roles = $this->getFieldRoleValues($form_values);
$role_settings = $this->competencySettings->get('roles') ?? [];
$new_values = [];
$completed = [];
foreach ($role_settings as $i => $setting) {
$role = $setting['role'];
if (empty($role)) {
continue;
}
if (!isset($existing_values[$role])) {
$existing_values[$role] = [
'correct' => 0,
'total' => 0,
'role' => $role,
'proposer' => NULL,
'approver' => NULL,
'proposed' => NULL,
'approved' => NULL,
];
}
$value = [
'role' => $role,
'correct' => $roles[$role]['correct'] ?? 0,
'total' => $roles[$role]['total'] ?? 0,
'proposer' => NULL,
'approver' => NULL,
'proposed' => $existing_values[$role]['proposed'] ?? NULL,
'approved' => $existing_values[$role]['approved'] ?? NULL,
];
if ($existing_values[$role]['proposer']) {
$value['proposer'] = $this->userStorage->load($existing_values[$role]['proposer']);
}
if ($existing_values[$role]['approver']) {
$value['approver'] = $this->userStorage->load($existing_values[$role]['approver']);
}
$complete = ($value['correct'] == $value['total']);
$existing_complete = $existing_values[$role]['proposer'];
$new_values[] = $value;
}
return $new_values;
}
/**
* Get the field role.
*
* @return array
* The field role.
*/
private function getFieldRoleValues($form_values) {
$roles = [];
foreach ($this->fieldDefinitions as $field_name => $field_definition) {
if ($field_definition->getType() != 'boolean') {
continue;
}
if ($field_name == 'revision_default') {
continue;
}
$role = $field_definition->getThirdPartySetting('knowledge', 'competency_role', '_none');
if ($role == '_none') {
continue;
}
if (!isset($roles[$role])) {
$roles[$role] = [
'correct' => 0,
'total' => 0,
'role' => $role,
];
}
$roles[$role]['total'] += 1;
if ($form_values[$field_name]['value'] == 1) {
$roles[$role]['correct'] += 1;
}
}
return $roles;
}
/**
* Get the existing values.
*/
private function getExistingValues(KnowledgeCompetencyInterface $competency) {
$roles = $competency->get('roles');
$existing = [];
foreach ($roles as $role) {
$r = $role->role;
$existing[$r] = [
'correct' => $role->correct,
'total' => $role->total,
'role' => $role->role,
'proposer' => $role->proposer,
'approver' => $role->approver,
'proposed' => $role->proposed,
'approved' => $role->approved,
];
}
return $existing;
}
}
