Skip to content
Snippets Groups Projects
Commit 64d1991e authored by John Voskuilen's avatar John Voskuilen
Browse files

Issue #3529071: Change WorkflowItem to ListStringItem

parent 04d1787f
Branches
Tags
No related merge requests found
Pipeline #517331 passed with warnings
......@@ -176,8 +176,9 @@ class WorkflowTransitionElement extends FormElement {
// @todo Repair $workflow->'name_as_title': no container if no details (schedule/comment).
$attribute_name = 'to_sid';
$attribute_key = 'widget';
// // Needed for radios, that need 1 value, not array.
$to_sid = $element[$attribute_name][$attribute_key]['#default_value'][0];
// Resetting $to_sid needed for radios, that need 1 value, not array.
// Default value may be empty when field is added for exising entities.
$to_sid = $element[$attribute_name][$attribute_key]['#default_value'][0] ?? '';
$widget = [
'#type' => $show_widget ? $options_type : 'radios',
'#title' => (!$workflow_settings['name_as_title'] && !$transition->isExecuted())
......
......@@ -464,8 +464,9 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition
$this->logError($message);
$valid = FALSE;
}
elseif (!$this->getFromState()) {
// @todo The page is not correctly refreshed after this error.
elseif (!$this->getFieldName()) {
// elseif (!$this->getFromSid()) {
// @todo The page is not correctly refreshed after this error.
$message = $this->t('You tried to set a Workflow State, but
the entity is not relevant. Please contact your system administrator.');
$this->messenger()->addError($message);
......
......@@ -2,16 +2,22 @@
namespace Drupal\workflow\Plugin\Field\FieldType;
use Drupal\Core\Entity\TypedData\EntityDataDefinition;
use Drupal\Core\Field\Attribute\FieldType;
use Drupal\Core\Field\EntityReferenceFieldItemList;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\OptGroup;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\DataReferenceDefinition;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\Core\Url;
use Drupal\options\Plugin\Field\FieldType\ListItemBase;
use Drupal\options\Plugin\Field\FieldType\ListStringItem;
use Drupal\workflow\Entity\Workflow;
use Drupal\workflow\Entity\WorkflowInterface;
use Drupal\workflow\Entity\WorkflowState;
......@@ -20,23 +26,36 @@ use Drupal\workflow\Entity\WorkflowTransitionInterface;
use Drupal\workflow\WorkflowTypeAttributeTrait;
/**
* Plugin implementation of the 'workflow' field type.
* Defines the 'workflow' field, referencing a workflow_transition entity type.
*
* @FieldType(
* id = "workflow",
* label = @Translation("Workflow state"),
* description = @Translation("This field stores Workflow values for a certain Workflow type from a list of allowed 'value => label' pairs, i.e. 'Publishing': 1 => unpublished, 2 => draft, 3 => published."),
* category = "workflow",
* default_widget = "workflow_default",
* default_formatter = "list_default",
* constraints = {
* "WorkflowField" = {}
* },
* cardinality = 1,
* )
* Supported settings (below the definition's 'settings' key) are:
* - target_type: The entity type to reference. Required.
*/
class WorkflowItem extends ListItemBase {
#[FieldType(
id: "workflow",
label: new TranslatableMarkup("Workflow state"),
description: [
new TranslatableMarkup("Stores Workflow state ID's for a certain Workflow type from a list of allowed 'value => label' pairs"),
new TranslatableMarkup("For example, 'Publishing': 1 => unpublished, 2 => draft, 3 => published"),
],
category: "workflow",
default_widget: "workflow_default",
// default_widget: "entity_reference_autocomplete",
default_formatter: "list_default",
// default_formatter: "entity_reference_label",
// list_class: EntityReferenceFieldItemList::class,
cardinality: 1,
constraints: [
'WorkflowField' => [],
],
module:"workflow",
)]
// class WorkflowItem extends EntityReferenceItem {
class WorkflowItem extends ListStringItem {
use MessengerTrait;
/*
* Add variables and get/set methods for Workflow property.
*/
......@@ -56,53 +75,55 @@ class WorkflowItem extends ListItemBase {
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
/**
* Property definitions of the contained properties.
*
* @see FileItem::getPropertyDefinitions()
*
* @var array
*/
static $propertyDefinitions;
/**
* Property definition of the item's target entity.
*
* Use underscore to avoid confusion with EntityTypeId.
* @todo Better use 'target_transition'.
*
* @var string
*/
$target_type = '_workflow_transition';
$target_bundle = $definition['settings']['target_bundle'] ?? '';
$definition['settings']['target_type'] = $target_type;
// Definitions vary by entity type and bundle, so key them accordingly.
$key = "{$target_type}:{$target_bundle}";
if (!isset($propertyDefinitions[$key])) {
$propertyDefinitions[$key]['value'] = DataDefinition::create('string')
->setLabel(t('Workflow state'))
->addConstraint('Length', ['max' => 128])
->setRequired(TRUE);
$propertyDefinitions[$key][$target_type] = DataDefinition::create('any')
// = DataDefinition::create('WorkflowTransition')
->setLabel(t('Transition'))
->setDescription(t('The WorkflowTransition setting the Workflow state.'))
->setComputed(TRUE)
// ->setClass('\Drupal\workflow\Entity\WorkflowTransition')
// ->setSetting('date source', 'value')
;
}
return $propertyDefinitions[$key];
// $properties = $properties
// + ListStringItem::propertyDefinitions($field_definition)
// + EntityReferenceItem::propertyDefinitions($field_definition);
$properties = parent::propertyDefinitions($field_definition);
// Note: Settings are set in static::defaultStorageSettings();
$settings = $field_definition->getSettings();
// When Item is ListStringItem, ListItemBase.
$properties['value'] = DataDefinition::create('string')
->setLabel(new TranslatableMarkup('Workflow state ID'))
->addConstraint('Length', ['max' => 128])
->setRequired(TRUE);
// When Item is EntityReferenceItem.
// Override parent integer ReferenceID for State key.
$properties['target_id'] = DataDefinition::create('string')
->setLabel(t('Workflow state ID'))
->addConstraint('Length', ['max' => 128])
->setRequired(TRUE);
$properties['entity'] = DataReferenceDefinition::create('entity')
// = DataDefinition::create('WorkflowTransition')
->setLabel(t('State'))
->setDescription(new TranslatableMarkup('The Workflow state.'))
// The entity object is computed out of the entity ID.
->setComputed(TRUE)
->setReadOnly(FALSE)
->setTargetDefinition(EntityDataDefinition::create($settings['target_type']));
// Custom property for storing Transition, next to State.
$properties['workflow_transition'] = DataReferenceDefinition::create('entity')
->setLabel(t('Transition'))
->setDescription(new TranslatableMarkup('The WorkflowTransition setting the Workflow state.'))
// The entity object is computed out of the entity ID.
//->setComputed(TRUE)
->setReadOnly(FALSE)
->setTargetDefinition(EntityDataDefinition::create($settings['target_transition']));
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
// $schema = ListStringItem::schema($field_definition);
// $schema = EntityReferenceItem::schema($field_definition);
$schema = parent::schema($field_definition);
$schema = [
'columns' => [
'value' => [
......@@ -115,17 +136,36 @@ class WorkflowItem extends ListItemBase {
'value' => ['value'],
],
];
return $schema;
}
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
return [
// 'handler' => 'default',
// 'handler_settings' => [],
] + parent::defaultFieldSettings();
}
/**
* {@inheritdoc}
*
* Note: Settings are used in static::propertyDefinitions();
*/
public static function defaultStorageSettings() {
$settings = [
'workflow_type' => '',
// When Item is ListStringItem, ListItemBase.
'allowed_values' => [],
'allowed_values_function' => 'workflow_state_allowed_values',
// When Item is EntityReferenceItem.
'target_type' => 'workflow_state',
'target_bundle' => '',
'handler' => 'default',
// Custom property for storing Transition, next to State.
'target_transition' => 'workflow_transition',
] + parent::defaultStorageSettings();
return $settings;
}
......@@ -243,6 +283,7 @@ class WorkflowItem extends ListItemBase {
* {@inheritdoc}
*/
public function isEmpty() {
// @todo $is_empty = parent::isEmpty();
$is_empty = empty($this->value);
return $is_empty;
}
......@@ -253,22 +294,60 @@ class WorkflowItem extends ListItemBase {
* Set both the Transition property AND the to_sid value.
*/
public function setValue($values, $notify = TRUE) {
if ($values instanceof WorkflowTransitionInterface) {
/** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $values */
$to_sid = $values->getToSid();
$keys = array_keys($this->definition->getPropertyDefinitions());
$values = [
// Attribute 'value'.
// Do not change the value for scheduled transition.
$keys[0] => $values->isScheduled() ? $values->getFromSid() : $to_sid,
// Attribute '_workflow_transition'.
$keys[1] => $values,
];
$transition = NULL;
$entity = $this->getEntity();
$field_name = $this->getFieldName();
switch (TRUE) {
case $values instanceof WorkflowTransitionInterface:
/** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $transition */
$transition = $values;
$sid = $transition->isScheduled()
? $transition->getFromSid()
: $transition->getToSid();
break;
case is_array($values) && isset($values['value']):
// Add provisions for ReferencedEntity.
$sid = $values['value'];
break;
default:
// Add provisions for ReferencedEntity.
$sid = $values;
break;
}
// $items may be empty on node with options widget, or upon initial setting.
$items = $entity->{$field_name} ?? NULL;
if ($items) {
$transition ??= WorkflowTransition::create([
'entity' => $entity,
'field_name' => $field_name,
'wid' => $this->getWorkflowId(),
'to_sid' => $sid,
]);
}
$values = [
'value' => $sid,
'target_id' => $sid,
'workflow_transition' => $transition,
];
parent::setValue($values, $notify);
}
/**
* Gets the item's Field name.
*
* @return string
* The Field name.
*/
public function getFieldName() {
$field_name = $this->getParent()->getName();
return $field_name;
}
/**
* Gets the item's WorkflowState (of the first item in ItemList).
*
......@@ -293,12 +372,11 @@ class WorkflowItem extends ListItemBase {
*/
public function getStateId() {
$sid = $this->value;
$sid ??= $this->getParent()->value;
return $sid;
}
/**
* Gets the item's '_workflow_transition' (of the first item in ItemList).
* Gets the item's WorkflowTransition (of the first item in ItemList).
*
* @return \Drupal\workflow\Entity\WorkflowTransitionInterface
* The Transition object, or NULL of not set.
......@@ -306,12 +384,11 @@ class WorkflowItem extends ListItemBase {
public function getTransition() {
$transition = NULL;
// Implements $transition = $entity->{$field_name}->__get('_workflow_transition') ?? NULL;
$target_type = $this->getSetting('target_transition');
$property = $this->get($target_type);
/** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $transition */
$property = $this->get('_workflow_transition');
$transition = $property->getValue();
// Create a transition, to pass to the form.
// @todo $this->set('_workflow_transition'); (?)
$transition ??= WorkflowTransition::create([
'entity' => $this->getEntity(),
'field_name' => $this->getParent()->getName(),
......@@ -320,20 +397,6 @@ class WorkflowItem extends ListItemBase {
return $transition;
}
/**
* {@inheritdoc}
*/
public function onChange($property_name, $notify = TRUE) {
// workflow_debug(__FILE__, __FUNCTION__, __LINE__); // @todo D8: test this snippet.
// @todo D8: use this function onChange for adding a line in table workflow_transition_*
// Enforce that the computed date is recalculated.
// if ($property_name == 'value') {
// $this->date = NULL;
// }
parent::onChange($property_name, $notify);
}
/**
* {@inheritdoc}
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment