class Workflow in Workflow 7.2
Same name and namespace in other branches
- 7 includes/Entity/Workflow.php \Workflow
Hierarchy
- class \Entity implements EntityInterface
- class \Workflow implements WorkflowInterface
Expanded class hierarchy of Workflow
37 string references to 'Workflow'
- theme_workflow_admin_ui_type_map_form in workflow_admin_ui/
workflow_admin_ui.page.type_map.inc - Theme the workflow type mapping form.
- theme_workflow_cleanup_form in workflow_cleanup/
workflow_cleanup.pages.inc - Theme the main form.
- WorkflowDefaultWidget::settings in includes/
Field/ WorkflowDefaultWidget.php - Returns the settings.
- WorkflowExampleTestCase::getInfo in includes/
Test/ WorkflowUnitTest.test - WorkflowItem::getInfo in includes/
Field/ WorkflowItem.php - Function, that gets replaced by the 'annotations' in D8. (
File
- includes/
Entity/ Workflow.php, line 12 - Contains workflow\includes\Entity\Workflow. Contains workflow\includes\Entity\WorkflowController.
View source
class Workflow extends Entity implements WorkflowInterface {
public $wid = 0;
public $name = '';
public $tab_roles = array();
public $options = array();
protected $creation_sid = 0;
protected $rebuilding = FALSE;
// Attached States.
public $states = NULL;
public $transitions = NULL;
/**
* CRUD functions.
*/
// public function __construct(array $values = array(), $entityType = NULL) {
// return parent::__construct($values, $entityType);
// }
public function __clone() {
// Clone the arrays of States and Transitions.
foreach ($this->states as &$state) {
$state = clone $state;
}
foreach ($this->transitions as &$transition) {
$transition = clone $transition;
}
}
/**
* Given information, update or insert a new workflow.
*
* This also handles importing, rebuilding, reverting from Features,
* as defined in workflow.features.inc.
*
* When changing this function, test with the following situations:
* - maintain Workflow in Admin UI;
* - clone Workflow in Admin UI;
* - create/revert/rebuild Workflow with Features; @see workflow.features.inc
* - save Workflow programmatically;
*/
public function save($create_creation_state = TRUE) {
// Are we saving a new Workflow?
$is_new = !empty($this->is_new);
// Are we rebuilding, reverting a new Workflow? @see workflow.features.inc
$is_rebuild = !empty($this->is_rebuild) || !empty($this->is_reverted);
if ($is_rebuild) {
$this->is_rebuild = TRUE;
$this
->preRebuild();
}
$return = parent::save();
// On either clone or rebuild from features.
if ($is_new || $is_rebuild) {
$this
->rebuildInternals();
if ($is_rebuild) {
// The above may have marked us overridden!
$this->status = ENTITY_IN_CODE;
parent::save();
}
}
// Make sure a Creation state exists.
if ($is_new) {
$state = $this
->getCreationState();
}
workflow_reset_cache($this->wid);
return $return;
}
/**
* Rebuild things that get saved with this entity.
*/
protected function preRebuild() {
// Remap roles. They can come from another system with shifted role IDs.
// See also https://drupal.org/node/1702626 .
$this->tab_roles = $this
->rebuildRoles($this->tab_roles);
// After update.php or import feature, label might be empty. @todo: remove in D8.
if (empty($this->label)) {
$this->label = $this->name;
}
}
/**
* Rebuild internals that get saved separately.
*/
protected function rebuildInternals() {
// Avoid recursive rebuilding.
if ($this->rebuilding) {
return;
}
$this->rebuilding = TRUE;
// Insert the type_map when building from Features.
if (isset($this->typeMap)) {
foreach ($this->typeMap as $node_type) {
workflow_insert_workflow_type_map($node_type, $this->wid);
}
}
// Index the existing states and transitions by name.
$db_name_map = WorkflowState::getStates($this->wid, TRUE);
// sid -> state.
$db_states = array();
// name -> state.
foreach ($db_name_map as $state) {
$db_states[$state
->getName()] = $state;
}
$db_transitions = array();
foreach (entity_load('WorkflowConfigTransition') as $transition) {
if ($transition->wid == $this->wid) {
$start_name = $db_name_map[$transition->sid]
->getName();
$end_name = $db_name_map[$transition->target_sid]
->getName();
$name = WorkflowConfigTransition::machineName($start_name, $end_name);
$db_transitions[$name] = $transition;
}
}
// Update/create states.
$states = isset($this->states) ? $this->states : array();
$saved_states = array();
// Saved states: key -> sid.
$saved_state_names = array();
foreach ($states as $key => $data) {
$data = (array) $data;
$name = $data['name'];
if (isset($db_states[$name])) {
$state = $db_states[$name];
}
else {
$state = $this
->createState($name, FALSE);
}
$state->wid = $this->wid;
$state->state = $data['state'];
$state->weight = $data['weight'];
$state->sysid = $data['sysid'];
if (!$data['status']) {
$this
->rebuildStateInactive($state);
}
$state->status = $data['status'];
$state
->save();
unset($db_states[$name]);
$saved_states[$key] = $state;
$saved_state_names[$state->sid] = $key;
}
// Update/create transitions.
$transitions = isset($this->transitions) ? $this->transitions : array();
foreach ($transitions as $name => $data) {
$data = (array) $data;
if (is_numeric($name)) {
if (isset($saved_states[$data['sid']]) && isset($saved_states[$data['target_sid']])) {
$start_state = $saved_states[$data['sid']];
// #2876303
$end_state = $saved_states[$data['target_sid']];
// #2876303
}
else {
$start_state = $this
->getState($data['sid']);
$end_state = $this
->getState($data['target_sid']);
}
}
else {
$start_state = $saved_states[$data['start_state']];
$end_state = $saved_states[$data['end_state']];
}
$name = WorkflowConfigTransition::machineName($start_state
->getName(), $end_state
->getName());
if (isset($db_transitions[$name])) {
$transition = $db_transitions[$name];
}
else {
$transition = $this
->createTransition($start_state->sid, $end_state->sid);
}
$transition->wid = $this->wid;
$transition->sid = $start_state->sid;
$transition->target_sid = $end_state->sid;
$transition->label = $data['label'];
$transition->roles = $this
->rebuildRoles($data['roles']);
$transition
->save();
unset($db_transitions[$name]);
}
// Any states/transitions left in $db_states/transitions need deletion.
foreach ($db_states as $state) {
$this
->rebuildStateInactive($state);
$state
->delete();
}
foreach ($db_transitions as $transition) {
$transition
->delete();
}
// Clear the caches, and set $this->states and $this->transitions.
$this->states = $this->transitions = NULL;
$this
->getStates(TRUE, TRUE);
$this
->getTransitions(FALSE, array(), TRUE);
$this->rebuilding = FALSE;
}
/**
* Handle a state becoming inactive during a rebuild.
*/
protected function rebuildStateInactive($state) {
if (!$state
->isActive()) {
return;
}
// TODO: What should we do in this case? Is this safe?
$state
->deactivate(NULL);
}
/**
* Given a wid, delete the workflow and its data.
*
* @deprecated: workflow_delete_workflows_by_wid() --> Workflow::delete().
*/
public function delete() {
$wid = $this->wid;
// Notify any interested modules before we delete the workflow.
// E.g., Workflow Node deletes the {workflow_type_map} record.
module_invoke_all('workflow', 'workflow delete', $wid, NULL, NULL, FALSE);
// Delete associated state (also deletes any associated transitions).
foreach ($this
->getStates($all = TRUE) as $state) {
$state
->deactivate(0);
$state
->delete();
}
// Delete the workflow.
db_delete('workflows')
->condition('wid', $wid)
->execute();
}
/**
* Validate the workflow. Generate a message if not correct.
*
* This function is used on the settings page of:
* - Workflow node: workflow_admin_ui_type_map_form()
* - Workflow field: WorkflowItem->settingsForm()
*
* @return bool
* $is_valid
*/
public function isValid() {
$is_valid = TRUE;
$workflow_name = $this
->getName();
$wid = $this
->getWorkflowId();
// Don't allow workflows with no states. There should always be a creation state.
$states = $this
->getStates($all = FALSE);
if (count($states) < 1) {
// That's all, so let's remind them to create some states.
$message = t('Workflow %workflow has no states defined, so it cannot be assigned to content yet.', array(
'%workflow' => $workflow_name,
));
drupal_set_message($message, 'warning');
// Skip allowing this workflow.
$is_valid = FALSE;
}
// Also check for transitions, at least out of the creation state. Use 'ALL' role.
$transitions = $this
->getTransitionsBySid($this
->getCreationSid(), $roles = 'ALL');
if (count($transitions) < 1) {
// That's all, so let's remind them to create some transitions.
$message = t('Workflow %workflow has no transitions defined, so it cannot be assigned to content yet.', array(
'%workflow' => $workflow_name,
));
drupal_set_message($message, 'warning');
// Skip allowing this workflow.
$is_valid = FALSE;
}
// If the Workflow is mapped to a node type, check if workflow->options is set.
if ($this
->getTypeMap() && !count($this->options)) {
// That's all, so let's remind them to create some transitions.
$message = t('Please maintain Workflow %workflow on its <a href="@url">settings</a> page.', array(
'%workflow' => $this
->getName(),
'@url' => url(WORKFLOW_ADMIN_UI_PATH . "/manage/{$wid}"),
));
drupal_set_message($message, 'warning');
// Skip allowing this workflow.
// $is_valid = FALSE;
}
return $is_valid;
}
/**
* Returns if the Workflow may be deleted.
*
* @return bool $is_deletable
* TRUE if a Workflow may safely be deleted.
*/
public function isDeletable() {
$is_deletable = FALSE;
// May not be deleted if a TypeMap exists.
if ($this
->getTypeMap()) {
return $is_deletable;
}
// May not be deleted if assigned to a Field.
foreach (_workflow_info_fields() as $field) {
if ($field['settings']['wid'] == $this->wid) {
return $is_deletable;
}
}
// May not be deleted if a State is assigned to a state.
foreach ($this
->getStates(TRUE) as $state) {
if ($state
->count()) {
return $is_deletable;
}
}
$is_deletable = TRUE;
return $is_deletable;
}
/**
* Property functions.
*/
/**
* Returns the workflow id.
*
* @return int
* $wid
*/
public function getWorkflowId() {
return $this->wid;
}
/**
* Create a new state for this workflow.
*
* @param string $name
* The untranslated human readable label of the state.
* @param bool $save
* Indicator if the new state must be saved. Normally, the new State is
* saved directly in the database. This is because you can use States only
* with Transitions, and they rely on State IDs which are generated
* magically when saving the State. But you may need a temporary state.
*
* @return WorkflowState
*/
public function createState($name, $save = TRUE) {
$wid = $this->wid;
$state = workflow_state_load_by_name($name, $wid);
if (!$state) {
$state = entity_create('WorkflowState', array(
'name' => $name,
'state' => $name,
'wid' => $wid,
));
if ($save) {
$state
->save();
}
}
$state
->setWorkflow($this);
// Maintain the new object in the workflow.
$this->states[$state->sid] = $state;
return $state;
}
/**
* Gets the initial state for a newly created entity.
*/
public function getCreationState() {
$sid = $this
->getCreationSid();
return $sid ? $this
->getState($sid) : $this
->createState(WORKFLOW_CREATION_STATE_NAME);
}
/**
* Gets the ID of the initial state for a newly created entity.
*/
public function getCreationSid() {
if (!$this->creation_sid) {
foreach ($this
->getStates($all = TRUE) as $state) {
if ($state
->isCreationState()) {
$this->creation_sid = $state->sid;
}
}
}
return $this->creation_sid;
}
/**
* Gets the first valid state ID, after the creation state.
*
* Uses WorkflowState::getOptions(), because this does a access check.
* The first State ID is user-dependent!
*/
public function getFirstSid($entity_type, $entity, $field_name, $user, $force) {
$creation_state = $this
->getCreationState();
$options = $creation_state
->getOptions($entity_type, $entity, $field_name, $user, $force);
if ($options) {
$keys = array_keys($options);
$sid = $keys[0];
}
else {
// This should never happen, but it did during testing.
drupal_set_message(t('There are no workflow states available. Please notify your site administrator.'), 'error');
$sid = 0;
}
return $sid;
}
/**
* Returns the next state for the current state.
*
* @param string $entity_type
* The type of the entity at hand.
* @param object $entity
* The entity at hand. May be NULL (E.g., on a Field settings page).
* @param $field_name
* @param $user
* @param bool $force
*
* @return int $sid
* A state ID.
*/
public function getNextSid($entity_type, $entity, $field_name, $user, $force = FALSE) {
$new_sid = workflow_node_current_state($entity, $entity_type, $field_name);
if ($new_sid && ($new_state = workflow_state_load_single($new_sid))) {
/* @var $current_state WorkflowState */
$options = $new_state
->getOptions($entity_type, $entity, $field_name, $user, $force);
// Loop over every option. To find the next one.
$flag = $new_state
->isCreationState();
foreach ($options as $sid => $name) {
if ($flag) {
$new_sid = $sid;
break;
}
if ($sid == $new_state->sid) {
$flag = TRUE;
}
}
}
return $new_sid;
}
/**
* Gets all states for a given workflow.
*
* @param mixed $all
* Indicates to which states to return.
* - TRUE = all, including Creation and Inactive;
* - FALSE = only Active states, not Creation;
* - 'CREATION' = only Active states, including Creation.
*
* @return array
* An array of WorkflowState objects.
*/
public function getStates($all = FALSE, $reset = FALSE) {
if ($this->states === NULL || $reset) {
$this->states = $this->wid ? WorkflowState::getStates($this->wid, $reset) : array();
}
// Do not unset, but add to array - you'll remove global objects otherwise.
$states = array();
foreach ($this->states as $state) {
if ($all === TRUE) {
$states[$state->sid] = $state;
}
elseif ($all === FALSE && ($state
->isActive() && !$state
->isCreationState())) {
$states[$state->sid] = $state;
}
elseif ($all == 'CREATION' && ($state
->isActive() || $state
->isCreationState())) {
$states[$state->sid] = $state;
}
}
return $states;
}
/**
* Gets a state for a given workflow.
*
* @param mixed $key
* A state ID or state Name.
*
* @return WorkflowState
* A WorkflowState object.
*/
public function getState($key) {
if (is_numeric($key)) {
return workflow_state_load_single($key, $this->wid);
}
else {
return workflow_state_load_by_name($key, $this->wid);
}
}
/**
* Creates a Transition for this workflow.
*/
public function createTransition($sid, $target_sid, $values = array()) {
$workflow = $this;
if (is_numeric($sid) && is_numeric($target_sid)) {
$values['sid'] = $sid;
$values['target_sid'] = $target_sid;
}
else {
$state = $workflow
->getState($sid);
$target_state = $workflow
->getState($target_sid);
$values['sid'] = $state->sid;
$values['target_sid'] = $target_state->sid;
}
// First check if this transition already exists.
if ($transitions = entity_load('WorkflowConfigTransition', FALSE, $values)) {
$transition = reset($transitions);
}
else {
$values['wid'] = $workflow->wid;
$transition = entity_create('WorkflowConfigTransition', $values);
$transition
->save();
}
$transition
->setWorkflow($this);
// Maintain the new object in the workflow.
$this->transitions[$transition->tid] = $transition;
return $transition;
}
/**
* Sorts all Transitions for this workflow, according to State weight.
*
* This is only needed for the Admin UI.
*/
public function sortTransitions() {
// Sort the transitions on state weight.
usort($this->transitions, '_workflow_transitions_sort_by_weight');
}
/**
* @inheritdoc
*/
public function getTransitions($tids = FALSE, array $conditions = array(), $reset = FALSE) {
$config_transitions = array();
// Get valid + creation states.
$states = $this
->getStates('CREATION');
// Get filters on 'from' states, 'to' states, roles.
$sid = isset($conditions['sid']) ? $conditions['sid'] : FALSE;
$target_sid = isset($conditions['target_sid']) ? $conditions['target_sid'] : FALSE;
$roles = isset($conditions['roles']) ? $conditions['roles'] : 'ALL';
// Cache all transitions in the workflow.
// We may have 0 transitions....
if ($this->transitions === NULL) {
$this->transitions = array();
// Get all transitions. (Even from other workflows. :-( )
$config_transitions = entity_load('WorkflowConfigTransition', $tids, array(), $reset);
foreach ($config_transitions as &$config_transition) {
if (isset($states[$config_transition->sid])) {
$config_transition
->setWorkflow($this);
$this->transitions[$config_transition->tid] = $config_transition;
}
}
$this
->sortTransitions();
}
$config_transitions = array();
foreach ($this->transitions as &$config_transition) {
if (!isset($states[$config_transition->sid])) {
// Not a valid transition for this workflow.
}
elseif ($sid && $sid != $config_transition->sid) {
// Not the requested 'from' state.
}
elseif ($target_sid && $target_sid != $config_transition->target_sid) {
// Not the requested 'to' state.
}
elseif ($roles == 'ALL' || $config_transition
->isAllowed($roles)) {
// Transition is allowed, permitted. Add to list.
$config_transition
->setWorkflow($this);
$config_transitions[$config_transition->tid] = $config_transition;
}
else {
// Transition is otherwise not allowed.
}
}
return $config_transitions;
}
public function getTransitionsByTid($tid, $roles = '', $reset = FALSE) {
$conditions = array(
'roles' => $roles,
);
return $this
->getTransitions(array(
$tid,
), $conditions, $reset);
}
public function getTransitionsBySid($sid, $roles = '', $reset = FALSE) {
$conditions = array(
'sid' => $sid,
'roles' => $roles,
);
return $this
->getTransitions(FALSE, $conditions, $reset);
}
public function getTransitionsByTargetSid($target_sid, $roles = '', $reset = FALSE) {
$conditions = array(
'target_sid' => $target_sid,
'roles' => $roles,
);
return $this
->getTransitions(FALSE, $conditions, $reset);
}
/**
* Get a specific transition. Therefore, use $roles = 'ALL'.
*/
public function getTransitionsBySidTargetSid($sid, $target_sid, $roles = 'ALL', $reset = FALSE) {
$conditions = array(
'sid' => $sid,
'target_sid' => $target_sid,
'roles' => $roles,
);
return $this
->getTransitions(FALSE, $conditions, $reset);
}
/**
* Gets a the type map for a given workflow.
*
* @param int $sid
* A state ID.
*
* @return array
* An array of typemaps.
*/
public function getTypeMap() {
$result = array();
$type_maps = module_exists('workflownode') ? workflow_get_workflow_type_map_by_wid($this->wid) : array();
foreach ($type_maps as $map) {
$result[] = $map->type;
}
return $result;
}
/**
* Gets a setting from the state object.
*/
public function getSetting($key, array $field = array()) {
switch ($key) {
case 'watchdog_log':
if (isset($this->options['watchdog_log'])) {
// This is set via Node API.
return $this->options['watchdog_log'];
}
elseif ($field) {
if (isset($field['settings']['watchdog_log'])) {
// This is set via Field API.
return $field['settings']['watchdog_log'];
}
}
drupal_set_message('Setting Workflow::getSetting(' . $key . ') does not exist', 'error');
break;
default:
drupal_set_message('Setting Workflow::getSetting(' . $key . ') does not exist', 'error');
}
}
/**
* Mimics Entity API functions.
*/
public function getName() {
return $this->name;
}
protected function defaultLabel() {
return isset($this->label) ? t('@label', array(
'@label' => $this->label,
)) : '';
}
protected function defaultUri() {
$wid = $this->wid;
return array(
'path' => WORKFLOW_ADMIN_UI_PATH . "/manage/{$wid}",
);
}
protected function rebuildRoles(array $roles) {
$new_roles = array();
// @todo: importing Roles is incomplete when user language is not English.
// function user_roles() translates DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID
$role_map = workflow_get_roles(NULL, FALSE);
// See also https://drupal.org/node/1702626 .
foreach ($roles as $key => $rid) {
if ($rid == WORKFLOW_ROLE_AUTHOR_RID) {
$new_roles[$rid] = $rid;
}
else {
if ($role = user_role_load_by_name($role_map[$rid])) {
$new_roles[$role->rid] = (int) $role->rid;
}
}
}
return $new_roles;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Entity:: |
protected | property | 1 | |
Entity:: |
protected | property | ||
Entity:: |
protected | property | ||
Entity:: |
protected | property | ||
Entity:: |
protected | property | ||
Entity:: |
public | function |
Builds a structured array representing the entity's content. Overrides EntityInterface:: |
1 |
Entity:: |
public | function |
Returns the bundle of the entity. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Returns the info of the type of the entity. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Returns the type of the entity. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Exports the entity. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Gets the raw, translated value of a property or field. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Checks if the entity has a certain exportable status. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Returns the entity identifier, i.e. the entities name or numeric id. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Returns the internal, numeric identifier. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Checks whether the entity is the default revision. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Returns the label of the entity. Overrides EntityInterface:: |
|
Entity:: |
protected | function | Set up the object instance on construction or unserializiation. | |
Entity:: |
public | function |
Returns the uri of the entity just as entity_uri(). Overrides EntityInterface:: |
|
Entity:: |
public | function |
Generate an array for rendering the entity. Overrides EntityInterface:: |
|
Entity:: |
public | function |
Returns the EntityMetadataWrapper of the entity. Overrides EntityInterface:: |
|
Entity:: |
public | function | 1 | |
Entity:: |
public | function | Magic method to only serialize what's necessary. | |
Entity:: |
public | function | Magic method to invoke setUp() on unserialization. | |
Workflow:: |
protected | property | ||
Workflow:: |
public | property | ||
Workflow:: |
public | property | ||
Workflow:: |
protected | property | ||
Workflow:: |
public | property | ||
Workflow:: |
public | property | ||
Workflow:: |
public | property | ||
Workflow:: |
public | property | ||
Workflow:: |
public | function |
Create a new state for this workflow. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |
Creates a Transition for this workflow. Overrides WorkflowInterface:: |
|
Workflow:: |
protected | function |
Defines the entity label if the 'entity_class_label' callback is used. Overrides Entity:: |
|
Workflow:: |
protected | function |
Override this in order to implement a custom default URI and specify
'entity_class_uri' as 'uri callback' hook_entity_info(). Overrides Entity:: |
|
Workflow:: |
public | function |
Given a wid, delete the workflow and its data. Overrides Entity:: |
|
Workflow:: |
public | function |
Gets the ID of the initial state for a newly created entity. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |
Gets the initial state for a newly created entity. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |
Gets the first valid state ID, after the creation state. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function | Mimics Entity API functions. | |
Workflow:: |
public | function |
Returns the next state for the current state. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function | Gets a setting from the state object. | |
Workflow:: |
public | function |
Gets a state for a given workflow. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |
Gets all states for a given workflow. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |
@inheritdoc Overrides WorkflowInterface:: |
|
Workflow:: |
public | function | ||
Workflow:: |
public | function | Get a specific transition. Therefore, use $roles = 'ALL'. | |
Workflow:: |
public | function | ||
Workflow:: |
public | function |
Overrides WorkflowInterface:: |
|
Workflow:: |
public | function | Gets a the type map for a given workflow. | |
Workflow:: |
public | function |
Returns the workflow id. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |
Returns if the Workflow may be deleted. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |
Validate the workflow. Generate a message if not correct. Overrides WorkflowInterface:: |
|
Workflow:: |
protected | function | Rebuild things that get saved with this entity. | |
Workflow:: |
protected | function | Rebuild internals that get saved separately. | |
Workflow:: |
protected | function | ||
Workflow:: |
protected | function | Handle a state becoming inactive during a rebuild. | |
Workflow:: |
public | function |
Given information, update or insert a new workflow. Overrides Entity:: |
|
Workflow:: |
public | function |
Sorts all Transitions for this workflow, according to State weight. Overrides WorkflowInterface:: |
|
Workflow:: |
public | function |