3 namespace Drupal\workflows\Entity;
5 use Drupal\Core\Config\Entity\ConfigEntityBase;
6 use Drupal\Core\Entity\EntityStorageInterface;
7 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
8 use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection;
9 use Drupal\workflows\Exception\RequiredStateMissingException;
10 use Drupal\workflows\WorkflowInterface;
13 * Defines the workflow entity.
17 * label = @Translation("Workflow"),
18 * label_collection = @Translation("Workflows"),
19 * label_singular = @Translation("workflow"),
20 * label_plural = @Translation("workflows"),
21 * label_count = @PluralTranslation(
22 * singular = "@count workflow",
23 * plural = "@count workflows",
26 * "access" = "Drupal\workflows\WorkflowAccessControlHandler",
27 * "list_builder" = "Drupal\workflows\WorkflowListBuilder",
29 * "add" = "Drupal\workflows\Form\WorkflowAddForm",
30 * "edit" = "Drupal\workflows\Form\WorkflowEditForm",
31 * "delete" = "Drupal\workflows\Form\WorkflowDeleteForm",
32 * "add-state" = "Drupal\workflows\Form\WorkflowStateAddForm",
33 * "edit-state" = "Drupal\workflows\Form\WorkflowStateEditForm",
34 * "delete-state" = "Drupal\workflows\Form\WorkflowStateDeleteForm",
35 * "add-transition" = "Drupal\workflows\Form\WorkflowTransitionAddForm",
36 * "edit-transition" = "Drupal\workflows\Form\WorkflowTransitionEditForm",
37 * "delete-transition" = "Drupal\workflows\Form\WorkflowTransitionDeleteForm",
39 * "route_provider" = {
40 * "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
43 * config_prefix = "workflow",
44 * admin_permission = "administer workflows",
51 * "add-form" = "/admin/config/workflow/workflows/add",
52 * "edit-form" = "/admin/config/workflow/workflows/manage/{workflow}",
53 * "delete-form" = "/admin/config/workflow/workflows/manage/{workflow}/delete",
54 * "add-state-form" = "/admin/config/workflow/workflows/manage/{workflow}/add_state",
55 * "add-transition-form" = "/admin/config/workflow/workflows/manage/{workflow}/add_transition",
56 * "collection" = "/admin/config/workflow/workflows",
66 class Workflow extends ConfigEntityBase implements WorkflowInterface, EntityWithPluginCollectionInterface {
83 * The workflow type plugin ID.
85 * @see \Drupal\workflows\WorkflowTypeManager
92 * The configuration for the workflow type plugin.
96 protected $type_settings = [];
99 * The workflow type plugin collection.
101 * @var \Drupal\Component\Plugin\LazyPluginCollection
103 protected $pluginCollection;
108 public function preSave(EntityStorageInterface $storage) {
109 $workflow_type = $this->getTypePlugin();
110 $missing_states = array_diff($workflow_type->getRequiredStates(), array_keys($this->getTypePlugin()->getStates()));
111 if (!empty($missing_states)) {
112 throw new RequiredStateMissingException(sprintf("Workflow type '{$workflow_type->label()}' requires states with the ID '%s' in workflow '{$this->id()}'", implode("', '", $missing_states)));
114 parent::preSave($storage);
120 public function getTypePlugin() {
121 return $this->getPluginCollection()->get($this->type);
127 public function getPluginCollections() {
128 return ['type_settings' => $this->getPluginCollection()];
132 * Encapsulates the creation of the workflow's plugin collection.
134 * @return \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection
135 * The workflow's plugin collection.
137 protected function getPluginCollection() {
138 if (!$this->pluginCollection && $this->type) {
139 $this->pluginCollection = new DefaultSingleLazyPluginCollection(\Drupal::service('plugin.manager.workflows.type'), $this->type, $this->type_settings);
141 return $this->pluginCollection;
145 * Loads all workflows of the provided type.
147 * @param string $type
148 * The workflow type to load all workflows for.
151 * An array of workflow objects of the provided workflow type, indexed by
154 * @see \Drupal\workflows\Annotation\WorkflowType
156 public static function loadMultipleByType($type) {
157 return self::loadMultiple(\Drupal::entityQuery('workflow')->condition('type', $type)->execute());
163 public function status() {
164 // In order for a workflow to be usable it must have at least one state.
165 return !empty($this->status) && !empty($this->getTypePlugin()->getStates());
171 public function onDependencyRemoval(array $dependencies) {
172 // Give the parent method and the workflow type plugin a chance to react
173 // to removed dependencies and report if either of these two made a change.
174 $parent_changed_entity = parent::onDependencyRemoval($dependencies);
175 $plugin_changed_entity = $this->getTypePlugin()->onDependencyRemoval($dependencies);
176 return $plugin_changed_entity || $parent_changed_entity;