View source
<?php
namespace Drupal\workflow;
use Drupal\Core\Config\Entity\DraggableListBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\workflow\Entity\WorkflowState;
class WorkflowStateListBuilder extends DraggableListBuilder {
public function load() {
$entities = [];
if (!($workflow = workflow_url_get_workflow())) {
return $entities;
}
$wid = $workflow
->id();
$entities = parent::load();
foreach ($entities as $key => $entity) {
if ($entity
->getWorkflowId() != $wid) {
unset($entities[$key]);
}
}
return $entities;
}
public function getFormId() {
return 'workflow_state_form';
}
public function buildHeader() {
$header['drag_handle'] = '';
$header['label_new'] = $this
->t('Label');
$header['id'] = $this
->t('ID');
$header['sysid'] = '';
$header['status'] = $this
->t('Active');
$header['reassign'] = $this
->t('Reassign');
$header['count'] = $this
->t('Count');
return $header + parent::buildHeader();
}
public function buildRow(EntityInterface $entity) {
$row = [];
if (!($workflow = workflow_url_get_workflow())) {
return $row;
}
$wid = $url_wid = $workflow
->id();
$state = $entity;
$sid = $state
->id();
$label = $state
->label();
$count = $state
->count();
$state_options = [
'' => ' ',
];
$state_options += workflow_get_workflow_state_names($wid, FALSE);
$current_state_options = [];
if ($state
->isActive() && !$state
->isCreationState() && $sid) {
$current_state = [
$sid => $state_options[$sid],
];
$current_state_options = array_diff($state_options, $current_state);
}
$row['drag_handle'] = [
'#type' => 'label',
];
$row['label_new'] = [
'#markup' => $label,
'#type' => 'textfield',
'#size' => 30,
'#maxlength' => 255,
'#default_value' => $label,
'#title' => NULL,
'#disabled' => !$state
->isActive(),
];
$row['id'] = [
'#type' => 'machine_name',
'#title' => NULL,
'#size' => 30,
'#description' => NULL,
'#disabled' => TRUE,
'#default_value' => $state
->id(),
'#required' => FALSE,
'#machine_name' => [
'exists' => [
$this,
'exists',
],
'source' => [
'states',
$state
->id(),
'label_new',
],
'replace_pattern' => '[^a-z0-9_()]+',
'error' => $this
->t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores.'),
],
];
$row['sysid'] = [
'#type' => 'value',
'#value' => $state->sysid,
];
$row['status'] = [
'#type' => 'checkbox',
'#default_value' => $state
->isActive(),
'#disabled' => $state
->isCreationState() || !$sid,
];
$row['reassign'] = [
'#type' => 'select',
'#options' => $current_state_options,
];
$row['count'] = [
'#type' => 'value',
'#value' => $count,
'#markup' => $count,
];
$row += parent::buildRow($entity);
if ($state
->isCreationState()) {
$row['#attributes']['class'] = array_diff($row['#attributes']['class'], [
'draggable',
]);
}
if (!$state
->isActive() || $state
->isCreationState() || !$sid || !$count) {
$row['reassign']['#type'] = 'hidden';
$row['reassign']['#disabled'] = TRUE;
}
return $row;
}
public function buildForm(array $form, FormStateInterface $form_state) {
if (!($workflow = workflow_url_get_workflow())) {
return $form;
}
$form = parent::buildForm($form, $form_state);
$form[$this->entitiesKey] += [
'#sticky' => TRUE,
];
$wid = $workflow
->id();
$state_options = workflow_get_workflow_state_names($wid, FALSE);
$form['#last_mohican'] = count($state_options) == 1;
$form['entities']['#prefix'] = '<div id="states_table_wrapper">';
$form['entities']['#suffix'] = '</div>';
if ($form_state
->getTriggeringElement() && $form_state
->getTriggeringElement()['#name'] === 'add_state') {
$sid = '';
$placeholder = $workflow
->createState($sid, FALSE);
$placeholder
->set('label', '');
$this->entities['placeholder'] = $placeholder;
$form['entities']['placeholder'] = $this
->buildRow($placeholder);
}
$form['actions']['submit']['#value'] = $this
->t('Save');
$form['actions']['add_state'] = [
'#name' => 'add_state',
'#type' => 'submit',
'#value' => $this
->t('Add State'),
'#ajax' => [
'callback' => '::addStateCallback',
'wrapper' => 'states_table_wrapper',
],
];
return $form;
}
public function getDefaultOperations(EntityInterface $entity) {
$operations = parent::getDefaultOperations($entity);
$state = $entity;
$operations += $this
->moduleHandler()
->invokeAll('workflow_operations', [
'state',
$state,
]);
return $operations;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
foreach ($form_state
->getValue($this->entitiesKey) as $sid => $value) {
$state = isset($this->entities[$sid]) ? $this->entities[$sid] : NULL;
if ($state && $state
->isActive() && !$value['status']) {
$args = [
'%state' => $state
->label(),
];
if (!$form['#last_mohican'] && $value['count'] > 0 && empty($value['reassign'])) {
$message = 'The %state state has content; you must
reassign the content to another state.';
$form_state
->setErrorByName("states'][{$sid}]['reassign'", $this
->t($message, $args));
}
}
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
if (!($workflow = workflow_url_get_workflow())) {
return [];
}
$creation_weight = -11;
$max_weight = -9;
foreach ($form_state
->getValue($this->entitiesKey) as $sid => $value) {
if (!isset($this->entities[$sid])) {
continue;
}
if (empty($value['label_new'])) {
continue;
}
$state = $this->entities[$sid];
if ($state && $state
->isActive() && !$value['status'] && $sid) {
$new_sid = $value['reassign'];
$new_state = WorkflowState::load($new_sid);
$args = [
'%workflow' => $workflow
->label(),
'%old_state' => $state
->label(),
'%new_state' => isset($new_state) ? $new_state
->label() : '',
];
if ($value['count'] > 0) {
if ($form['#last_mohican']) {
$new_sid = NULL;
$message = 'Removing workflow states from content in the %workflow.';
$this
->messenger()
->addStatus($this
->t($message, $args));
$message = 'Since you have deleted the last available
workflow state in this workflow, all content items
which with this %workflow workflow have their workflow state
removed.';
$this
->messenger()
->addWarning($this
->t($message, $args));
}
else {
$message = 'Reassigning content from %old_state to %new_state.';
$this
->messenger()
->addStatus($this
->t($message, $args));
}
}
$state
->deactivate($new_sid);
$message = $this
->t('Deactivated workflow state %old_state in %workflow.', $args);
\Drupal::logger('workflow')
->notice($message, []);
$this
->messenger()
->addStatus($message);
}
$weight = $value['weight'];
if ($value['sysid'] == WORKFLOW_CREATION_STATE) {
$weight = $creation_weight;
}
elseif ($sid === 'placeholder') {
$state
->set('id', $value['id']);
$max_weight = max($max_weight, $state
->get($this->weightKey));
$weight = $max_weight + 1;
}
$state
->set($this->weightKey, $weight);
$state
->set('label', $value['label_new']);
$state
->set('status', $value['status']);
try {
$state
->save();
} catch (\Exception $e) {
$args = [
'%id' => $state
->id(),
];
return $this
->messenger()
->addError($this
->t('ID %id already exists', $args));
}
}
if ($form_state
->getTriggeringElement()['#name'] === 'add_state') {
$input = $form_state
->getUserInput();
unset($input['entities']['placeholder']['label_new']);
$form_state
->setUserInput($input);
$form_state
->setRebuild();
}
return $this
->messenger()
->addStatus($this
->t('The Workflow states have been updated.'));
}
public function addStateCallback(array &$form, FormStateInterface $form_state) {
return $form['entities'];
}
public function exists($name, array $element, FormStateInterface $form_state) {
$state_names = [];
foreach ($form_state
->getValue($this->entitiesKey) as $sid => $value) {
$state_names[] = $value['id'];
}
$state_names = array_map('strtolower', $state_names);
$result = array_unique(array_diff_assoc($state_names, array_unique($state_names)));
if (in_array($name, $result)) {
return TRUE;
}
return FALSE;
}
}