Commit 6772e2df authored by larowlan's avatar larowlan

Issue #2849827 by Sam152, timmillwood, larowlan: Move workflow "settings"...

Issue #2849827 by Sam152, timmillwood, larowlan: Move workflow "settings" setters and getters to WorkflowTypeInterface
parent e562b4e1
......@@ -5,59 +5,55 @@ dependencies:
- content_moderation
id: editorial
label: 'Editorial workflow'
states:
archived:
label: Archived
weight: 5
draft:
label: Draft
weight: -5
published:
label: Published
weight: 0
transitions:
archive:
label: Archive
from:
- published
to: archived
weight: 2
archived_draft:
label: 'Restore to Draft'
from:
- archived
to: draft
weight: 3
archived_published:
label: Restore
from:
- archived
to: published
weight: 4
create_new_draft:
label: 'Create New Draft'
from:
- draft
- published
to: draft
weight: 0
publish:
label: Publish
from:
- draft
- published
to: published
weight: 1
type: content_moderation
type_settings:
states:
archived:
label: Archived
weight: 5
published: false
default_revision: true
draft:
label: Draft
published: false
default_revision: false
weight: -5
published:
label: Published
published: true
default_revision: true
weight: 0
transitions:
create_new_draft:
label: 'Create New Draft'
to: draft
weight: 0
from:
- draft
- published
publish:
label: Publish
to: published
weight: 1
from:
- draft
- published
archive:
label: Archive
from:
- published
to: archived
weight: 2
archived_draft:
label: 'Restore to Draft'
from:
- archived
to: draft
weight: 3
archived_published:
label: Restore
from:
- archived
to: published
weight: 4
entity_types: { }
......@@ -6,22 +6,30 @@ views.filter.latest_revision:
type: string
label: 'Value'
content_moderation.state:
type: workflows.state
mapping:
published:
type: boolean
label: 'Is published'
default_revision:
type: boolean
label: 'Is default revision'
workflow.type_settings.content_moderation:
type: mapping
mapping:
states:
type: sequence
label: 'Additional state configuration for content moderation'
label: 'Content moderation states'
sequence:
type: mapping
type: content_moderation.state
label: 'States'
mapping:
published:
type: boolean
label: 'Is published'
default_revision:
type: boolean
label: 'Is default revision'
transitions:
type: sequence
sequence:
type: workflows.transition
label: 'Transitions'
entity_types:
type: sequence
label: 'Entity types'
......
......@@ -91,20 +91,6 @@ public static function create(ContainerInterface $container, array $configuratio
);
}
/**
* {@inheritdoc}
*/
public function initializeWorkflow(WorkflowInterface $workflow) {
$workflow
->addState('draft', $this->t('Draft'))
->setStateWeight('draft', -5)
->addState('published', $this->t('Published'))
->setStateWeight('published', 0)
->addTransition('create_new_draft', $this->t('Create New Draft'), ['draft', 'published'], 'draft')
->addTransition('publish', $this->t('Publish'), ['draft', 'published'], 'published');
return $workflow;
}
/**
* {@inheritdoc}
*/
......@@ -119,7 +105,7 @@ public function checkWorkflowAccess(WorkflowInterface $entity, $operation, Accou
* {@inheritdoc}
*/
public function decorateState(StateInterface $state) {
if (isset($this->configuration['states'][$state->id()])) {
if (isset($this->configuration['states'][$state->id()]['published']) && isset($this->configuration['states'][$state->id()]['default_revision'])) {
$state = new ContentModerationState($state, $this->configuration['states'][$state->id()]['published'], $this->configuration['states'][$state->id()]['default_revision']);
}
else {
......@@ -243,16 +229,39 @@ public function addEntityTypeAndBundle($entity_type_id, $bundle_id) {
* {@inheritdoc}
*/
public function defaultConfiguration() {
// This plugin does not store anything per transition.
return [
'states' => [
'draft' => [
'label' => 'Draft',
'published' => FALSE,
'default_revision' => FALSE,
'weight' => 0,
],
'published' => [
'label' => 'Published',
'published' => TRUE,
'default_revision' => TRUE,
'weight' => 1,
],
],
'transitions' => [
'create_new_draft' => [
'label' => 'Create New Draft',
'to' => 'draft',
'weight' => 0,
'from' => [
'draft',
'published',
],
],
'publish' => [
'label' => 'Publish',
'to' => 'published',
'weight' => 1,
'from' => [
'draft',
'published',
],
],
],
'entity_types' => [],
......
......@@ -50,6 +50,9 @@ public function testNewWorkflow() {
$this->assertSession()->pageTextContains('Create New Draft');
$this->assertSession()->pageTextContains('Publish');
$this->assertSession()->linkByHrefNotExists('/admin/config/workflow/workflows/manage/test_workflow/state/draft/delete');
$this->assertSession()->linkByHrefNotExists('/admin/config/workflow/workflows/manage/test_workflow/state/published/delete');
// Ensure after a workflow is created, the bundle information can be
// refreshed.
$entity_bundle_info->clearCachedBundles();
......@@ -63,6 +66,15 @@ public function testNewWorkflow() {
'type_settings[content_moderation][default_revision]' => FALSE,
], 'Save');
$this->assertSession()->pageTextContains('Created Test State state.');
$this->assertSession()->linkByHrefExists('/admin/config/workflow/workflows/manage/test_workflow/state/test_state/delete');
// Check there is a link to delete a default transition.
$this->assertSession()->linkByHrefExists('/admin/config/workflow/workflows/manage/test_workflow/transition/publish/delete');
// Delete the transition.
$this->drupalGet('/admin/config/workflow/workflows/manage/test_workflow/transition/publish/delete');
$this->submitForm([], 'Delete');
// The link to delete the transition should now be gone.
$this->assertSession()->linkByHrefNotExists('/admin/config/workflow/workflows/manage/test_workflow/transition/publish/delete');
// Ensure that the published settings cannot be changed.
$this->drupalGet('admin/config/workflow/workflows/manage/test_workflow/state/published');
......
......@@ -55,37 +55,13 @@ public function permissionsTestCases() {
'id' => 'simple_workflow',
'label' => 'Simple Workflow',
'type' => 'content_moderation',
'transitions' => [
'publish' => [
'label' => 'Publish',
'from' => ['draft'],
'to' => 'published',
'weight' => 0,
],
'unpublish' => [
'label' => 'Unpublish',
'from' => ['published'],
'to' => 'draft',
'weight' => 0,
],
],
'states' => [
'draft' => [
'label' => 'Draft',
'weight' => -5,
],
'published' => [
'label' => 'Published',
'weight' => 0,
],
],
],
[
'use simple_workflow transition publish' => [
'title' => 'Use <em class="placeholder">Publish</em> transition from <em class="placeholder">Simple Workflow</em> workflow.',
],
'use simple_workflow transition unpublish' => [
'title' => 'Use <em class="placeholder">Unpublish</em> transition from <em class="placeholder">Simple Workflow</em> workflow.',
'use simple_workflow transition create_new_draft' => [
'title' => 'Use <em class="placeholder">Create New Draft</em> transition from <em class="placeholder">Simple Workflow</em> workflow.',
],
],
],
......
......@@ -37,9 +37,6 @@ class ContentModerationWorkflowTypeApiTest extends KernelTestBase {
protected function setUp() {
parent::setUp();
$this->workflow = Workflow::create(['id' => 'test', 'type' => 'content_moderation']);
$this->workflow
->addState('draft', 'Draft')
->addState('published', 'Published');
}
/**
......
......@@ -8,8 +8,8 @@
use Drupal\Core\Session\AccountInterface;
use Drupal\content_moderation\StateTransitionValidation;
use Drupal\Tests\UnitTestCase;
use Drupal\workflow_type_test\Plugin\WorkflowType\TestType;
use Drupal\workflows\Entity\Workflow;
use Drupal\workflows\WorkflowTypeInterface;
use Drupal\workflows\WorkflowTypeManager;
use Prophecy\Argument;
......@@ -62,14 +62,8 @@ protected function setUpModerationInformation(ContentEntityInterface $entity) {
// Create a container so that the plugin manager and workflow type can be
// mocked.
$container = new ContainerBuilder();
$workflow_type = $this->prophesize(WorkflowTypeInterface::class);
$workflow_type->setConfiguration(Argument::any())->will(function ($arguments) {
$this->getConfiguration()->willReturn($arguments[0]);
});
$workflow_type->decorateState(Argument::any())->willReturnArgument(0);
$workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
$workflow_manager = $this->prophesize(WorkflowTypeManager::class);
$workflow_manager->createInstance('content_moderation', Argument::any())->willReturn($workflow_type->reveal());
$workflow_manager->createInstance('content_moderation', Argument::any())->willReturn(new TestType([], '', []));
$container->set('plugin.manager.workflows.type', $workflow_manager->reveal());
\Drupal::setContainer($container);
......
......@@ -14,38 +14,32 @@ workflows.workflow.*:
type_settings:
type: workflow.type_settings.[%parent.type]
label: 'Custom settings for workflow type'
states:
type: sequence
label: 'States'
sequence:
type: mapping
label: 'State'
mapping:
label:
type: label
label: 'Label'
weight:
type: integer
label: 'Weight'
transitions:
workflows.state:
type: mapping
mapping:
label:
type: label
label: 'Label'
weight:
type: integer
label: 'Weight'
workflows.transition:
type: mapping
mapping:
label:
type: label
label: 'Transition label'
from:
type: sequence
label: 'Transitions'
label: 'From state IDs'
sequence:
type: mapping
label: 'Transition from state to state'
mapping:
label:
type: label
label: 'Transition label'
from:
type: sequence
label: 'From state IDs'
sequence:
type: string
label: 'From state ID'
to:
type: string
label: 'To state ID'
weight:
type: integer
label: 'Weight'
type: string
label: 'From state ID'
to:
type: string
label: 'To state ID'
weight:
type: integer
label: 'Weight'
......@@ -88,7 +88,8 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
$entity->addState($values['id'], $values['label']);
if (isset($values['type_settings'])) {
$configuration = $entity->getTypePlugin()->getConfiguration();
$configuration['states'][$values['id']] = $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
// @todo move to submitStateConfigurationForm. #2849827.
$configuration['states'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
$entity->set('type_settings', $configuration);
}
}
......
......@@ -127,7 +127,7 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
$entity->setStateLabel($values['id'], $values['label']);
if (isset($values['type_settings'])) {
$configuration = $entity->getTypePlugin()->getConfiguration();
$configuration['states'][$values['id']] = $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
$configuration['states'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
$entity->set('type_settings', $configuration);
}
}
......
......@@ -107,7 +107,7 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
$entity->addTransition($values['id'], $values['label'], array_filter($values['from']), $values['to']);
if (isset($values['type_settings'])) {
$configuration = $entity->getTypePlugin()->getConfiguration();
$configuration['transitions'][$values['id']] = $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
$configuration['transitions'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
$entity->set('type_settings', $configuration);
}
}
......
......@@ -130,7 +130,7 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
$entity->setTransitionFromStates($values['id'], array_filter($values['from']));
if (isset($values['type_settings'])) {
$configuration = $entity->getTypePlugin()->getConfiguration();
$configuration['transitions'][$values['id']] = $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
$configuration['transitions'][$values['id']] += $values['type_settings'][$entity->getTypePlugin()->getPluginId()];
$entity->set('type_settings', $configuration);
}
}
......
......@@ -51,7 +51,7 @@ class State implements StateInterface {
* @param int $weight
* The state's weight.
*/
public function __construct(WorkflowInterface $workflow, $id, $label, $weight = 0) {
public function __construct(WorkflowTypeInterface $workflow, $id, $label, $weight = 0) {
$this->workflow = $workflow;
$this->id = $id;
$this->label = $label;
......
......@@ -69,7 +69,7 @@ class Transition implements TransitionInterface {
* @param int $weight
* (optional) The transition's weight. Defaults to 0.
*/
public function __construct(WorkflowInterface $workflow, $id, $label, array $from_state_ids, $to_state_id, $weight = 0) {
public function __construct(WorkflowTypeInterface $workflow, $id, $label, array $from_state_ids, $to_state_id, $weight = 0) {
$this->workflow = $workflow;
$this->id = $id;
$this->label = $label;
......
......@@ -23,6 +23,8 @@ interface WorkflowInterface extends ConfigEntityInterface {
*
* @return \Drupal\workflows\WorkflowInterface
* The workflow entity.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function addState($state_id, $label);
......@@ -34,6 +36,8 @@ public function addState($state_id, $label);
*
* @return bool
* TRUE if the workflow has a state with the provided ID, FALSE if not.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function hasState($state_id);
......@@ -48,6 +52,8 @@ public function hasState($state_id);
*
* @throws \InvalidArgumentException
* Thrown if $state_ids contains a state ID that does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function getStates($state_ids = NULL);
......@@ -62,6 +68,8 @@ public function getStates($state_ids = NULL);
*
* @throws \InvalidArgumentException
* Thrown if $state_id does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function getState($state_id);
......@@ -75,6 +83,8 @@ public function getState($state_id);
*
* @return \Drupal\workflows\WorkflowInterface
* The workflow entity.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function setStateLabel($state_id, $label);
......@@ -88,6 +98,8 @@ public function setStateLabel($state_id, $label);
*
* @return \Drupal\workflows\WorkflowInterface
* The workflow entity.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function setStateWeight($state_id, $weight);
......@@ -102,9 +114,21 @@ public function setStateWeight($state_id, $weight);
*
* @throws \InvalidArgumentException
* Thrown if $state_id does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function deleteState($state_id);
/**
* Gets the initial state for the workflow.
*
* @return \Drupal\workflows\StateInterface
* The initial state.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function getInitialState();
/**
* Adds a transition to the workflow.
*
......@@ -122,6 +146,8 @@ public function deleteState($state_id);
*
* @throws \InvalidArgumentException
* Thrown if either state does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function addTransition($id, $label, array $from_state_ids, $to_state_id);
......@@ -136,6 +162,8 @@ public function addTransition($id, $label, array $from_state_ids, $to_state_id);
*
* @throws \InvalidArgumentException
* Thrown if $transition_id does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function getTransition($transition_id);
......@@ -147,6 +175,8 @@ public function getTransition($transition_id);
*
* @return bool
* TRUE if the transition exists, FALSE if not.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function hasTransition($transition_id);
......@@ -162,6 +192,8 @@ public function hasTransition($transition_id);
*
* @throws \InvalidArgumentException
* Thrown if $transition_ids contains a transition ID that does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function getTransitions(array $transition_ids = NULL);
......@@ -176,6 +208,8 @@ public function getTransitions(array $transition_ids = NULL);
*
* @return array
* The transition IDs for a state for the provided direction.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function getTransitionsForState($state_id, $direction = 'from');
......@@ -192,6 +226,8 @@ public function getTransitionsForState($state_id, $direction = 'from');
*
* @throws \InvalidArgumentException
* Thrown if the transition does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function getTransitionFromStateToState($from_state_id, $to_state_id);
......@@ -205,6 +241,8 @@ public function getTransitionFromStateToState($from_state_id, $to_state_id);
*
* @return bool
* TRUE if the transition exists, FALSE if not.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function hasTransitionFromStateToState($from_state_id, $to_state_id);
......@@ -221,6 +259,8 @@ public function hasTransitionFromStateToState($from_state_id, $to_state_id);
*
* @throws \InvalidArgumentException
* Thrown if the transition does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function setTransitionLabel($transition_id, $label);
......@@ -237,6 +277,8 @@ public function setTransitionLabel($transition_id, $label);
*
* @throws \InvalidArgumentException
* Thrown if the transition does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function setTransitionWeight($transition_id, $weight);
......@@ -253,6 +295,8 @@ public function setTransitionWeight($transition_id, $weight);
*
* @throws \InvalidArgumentException
* Thrown if the transition does not exist or the states do not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function setTransitionFromStates($transition_id, array $from_state_ids);
......@@ -267,6 +311,8 @@ public function setTransitionFromStates($transition_id, array $from_state_ids)
*
* @throws \InvalidArgumentException
* Thrown if the transition does not exist.
*
* @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
*/
public function deleteTransition($transition_id);
......
......@@ -67,14 +67,6 @@ public function checkWorkflowAccess(WorkflowInterface $entity, $operation, Accou
*/
public function decorateState(StateInterface $state);
/**
* React to the removal of a state from a workflow.
*
* @param string $state_id
* The state ID of the state that is being removed.
*/
public function deleteState($state_id);
/**
* Decorates transitions so the WorkflowType can add additional information.
* @param \Drupal\workflows\TransitionInterface $transition
......@@ -85,14 +77,6 @@ public function deleteState($state_id);
*/
public function decorateTransition(TransitionInterface $transition);
/**
* React to the removal of a transition from a workflow.
*
* @param string $transition_id
* The transition ID of the transition that is being removed.
*/
public function deleteTransition($transition_id);
/**
* Gets the initial state for the workflow.
*
......@@ -170,4 +154,264 @@ public function getRequiredStates();
*/
public function onDependencyRemoval(array $dependencies);
/**
* Adds a state to the workflow.
*
* @param string $state_id
* The state's ID.
* @param string $label
* The state's label.
*
* @return \Drupal\workflows\WorkflowTypeInterface
* The workflow type plugin.
*
* @throws \InvalidArgumentException
* Thrown if a state already exists or state ID is invalid.
*/
public function addState($state_id, $label);
/**
* Determines if the workflow has a state with the provided ID.
*
* @param string $state_id
* The state's ID.
*
* @return bool
* TRUE if the workflow has a state with the provided ID, FALSE if not.
*/
public function hasState($state_id);
/**
* Gets state objects for the provided state IDs.
*
* @param string[] $state_ids
* A list of state IDs to get. If NULL then all states will be returned.
*
* @return \Drupal\workflows\StateInterface[]
* An array of workflow states.
*
* @throws \InvalidArgumentException
* Thrown if $state_ids contains a state ID that does not exist.
*/
public function getStates($state_ids = NULL);
/**
* Gets a workflow state.
*
* @param string $state_id
* The state's ID.
*
* @return \Drupal\workflows\StateInterface
* The workflow state.
*
* @throws \InvalidArgumentException
* Thrown if $state_id does not exist.
*/
public function getState($state_id);
/**