Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / workflows / src / Entity / Workflow.php
1 <?php
2
3 namespace Drupal\workflows\Entity;
4
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;
11
12 /**
13  * Defines the workflow entity.
14  *
15  * @ConfigEntityType(
16  *   id = "workflow",
17  *   label = @Translation("Workflow"),
18  *   label_collection = @Translation("Workflows"),
19  *   handlers = {
20  *     "access" = "Drupal\workflows\WorkflowAccessControlHandler",
21  *     "list_builder" = "Drupal\workflows\WorkflowListBuilder",
22  *     "form" = {
23  *       "add" = "Drupal\workflows\Form\WorkflowAddForm",
24  *       "edit" = "Drupal\workflows\Form\WorkflowEditForm",
25  *       "delete" = "Drupal\workflows\Form\WorkflowDeleteForm",
26  *       "add-state" = "Drupal\workflows\Form\WorkflowStateAddForm",
27  *       "edit-state" = "Drupal\workflows\Form\WorkflowStateEditForm",
28  *       "delete-state" = "Drupal\workflows\Form\WorkflowStateDeleteForm",
29  *       "add-transition" = "Drupal\workflows\Form\WorkflowTransitionAddForm",
30  *       "edit-transition" = "Drupal\workflows\Form\WorkflowTransitionEditForm",
31  *       "delete-transition" = "Drupal\workflows\Form\WorkflowTransitionDeleteForm",
32  *     },
33  *     "route_provider" = {
34  *       "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
35  *     },
36  *   },
37  *   config_prefix = "workflow",
38  *   admin_permission = "administer workflows",
39  *   entity_keys = {
40  *     "id" = "id",
41  *     "label" = "label",
42  *     "uuid" = "uuid",
43  *   },
44  *   links = {
45  *     "add-form" = "/admin/config/workflow/workflows/add",
46  *     "edit-form" = "/admin/config/workflow/workflows/manage/{workflow}",
47  *     "delete-form" = "/admin/config/workflow/workflows/manage/{workflow}/delete",
48  *     "add-state-form" = "/admin/config/workflow/workflows/manage/{workflow}/add_state",
49  *     "add-transition-form" = "/admin/config/workflow/workflows/manage/{workflow}/add_transition",
50  *     "collection" = "/admin/config/workflow/workflows",
51  *   },
52  *   config_export = {
53  *     "id",
54  *     "label",
55  *     "type",
56  *     "type_settings",
57  *   },
58  * )
59  */
60 class Workflow extends ConfigEntityBase implements WorkflowInterface, EntityWithPluginCollectionInterface {
61
62   /**
63    * The Workflow ID.
64    *
65    * @var string
66    */
67   protected $id;
68
69   /**
70    * The workflow label.
71    *
72    * @var string
73    */
74   protected $label;
75
76   /**
77    * The workflow type plugin ID.
78    *
79    * @see \Drupal\workflows\WorkflowTypeManager
80    *
81    * @var string
82    */
83   protected $type;
84
85   /**
86    * The configuration for the workflow type plugin.
87    *
88    * @var array
89    */
90   protected $type_settings = [];
91
92   /**
93    * The workflow type plugin collection.
94    *
95    * @var \Drupal\Component\Plugin\LazyPluginCollection
96    */
97   protected $pluginCollection;
98
99   /**
100    * {@inheritdoc}
101    */
102   public function preSave(EntityStorageInterface $storage) {
103     $workflow_type = $this->getTypePlugin();
104     $missing_states = array_diff($workflow_type->getRequiredStates(), array_keys($this->getTypePlugin()->getStates()));
105     if (!empty($missing_states)) {
106       throw new RequiredStateMissingException(sprintf("Workflow type '{$workflow_type->label()}' requires states with the ID '%s' in workflow '{$this->id()}'", implode("', '", $missing_states)));
107     }
108     parent::preSave($storage);
109   }
110
111   /**
112    * {@inheritdoc}
113    */
114   public function getTypePlugin() {
115     return $this->getPluginCollection()->get($this->type);
116   }
117
118   /**
119    * {@inheritdoc}
120    */
121   public function getPluginCollections() {
122     return ['type_settings' => $this->getPluginCollection()];
123   }
124
125   /**
126    * Encapsulates the creation of the workflow's plugin collection.
127    *
128    * @return \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection
129    *   The workflow's plugin collection.
130    */
131   protected function getPluginCollection() {
132     if (!$this->pluginCollection && $this->type) {
133       $this->pluginCollection = new DefaultSingleLazyPluginCollection(\Drupal::service('plugin.manager.workflows.type'), $this->type, $this->type_settings);
134     }
135     return $this->pluginCollection;
136   }
137
138   /**
139    * Loads all workflows of the provided type.
140    *
141    * @param string $type
142    *   The workflow type to load all workflows for.
143    *
144    * @return static[]
145    *   An array of workflow objects of the provided workflow type, indexed by
146    *   their IDs.
147    *
148    *  @see \Drupal\workflows\Annotation\WorkflowType
149    */
150   public static function loadMultipleByType($type) {
151     return self::loadMultiple(\Drupal::entityQuery('workflow')->condition('type', $type)->execute());
152   }
153
154   /**
155    * {@inheritdoc}
156    */
157   public function status() {
158     // In order for a workflow to be usable it must have at least one state.
159     return !empty($this->status) && !empty($this->getTypePlugin()->getStates());
160   }
161
162   /**
163    * {@inheritdoc}
164    */
165   public function onDependencyRemoval(array $dependencies) {
166     // Give the parent method and the workflow type plugin a chance to react
167     // to removed dependencies and report if either of these two made a change.
168     $parent_changed_entity = parent::onDependencyRemoval($dependencies);
169     $plugin_changed_entity = $this->getTypePlugin()->onDependencyRemoval($dependencies);
170     return $plugin_changed_entity || $parent_changed_entity;
171   }
172
173 }