You are here

class WorkflowFeaturesController in Workflow 7.2

Default controller handling features integration.

Hierarchy

Expanded class hierarchy of WorkflowFeaturesController

1 string reference to 'WorkflowFeaturesController'
workflow_entity_info in ./workflow.entity.inc
Implements hook_entity_info().

File

./workflow.features.inc, line 20
Provides Features integration for Workflow using the CRUD API.

View source
class WorkflowFeaturesController extends EntityDefaultFeaturesController {

  /**
   * Generates the result for hook_features_export().
   */
  public function export($data, &$export, $module_name = '') {
    $pipe = parent::export($data, $export, $module_name);
    foreach ($data as $workflow_name) {
      if ($workflow = workflow_load_by_name($workflow_name)) {

        // Add dependency on workflow_node.
        if (count($workflow
          ->getTypeMap())) {
          $export['dependencies']['workflownode'] = 'workflownode';
        }
      }
    }
    return $pipe;
  }

  /**
   * Generates the result for hook_features_export_render().
   *
   * This is a copy of the parent, adding 'system_roles'.
   * The workflow is imported in the target system with Workflow::save().
   */
  public function export_render($module, $data, $export = NULL) {
    $translatables = $code = array();
    $code[] = '  $workflows = array();';
    $code[] = '';
    foreach ($data as $identifier) {

      // Clone workflow to make sure changes are not propagated to original.
      if ($workflow = entity_load_single($this->type, $identifier)) {
        $this
          ->export_render_workflow($workflow, $identifier, $code);
      }
    }
    $code[] = '  return $workflows;';
    $code = implode("\n", $code);
    $hook = isset($this->info['export']['default hook']) ? $this->info['export']['default hook'] : 'default_' . $this->type;
    return array(
      $hook => $code,
    );
  }

  /**
   * Renders the provided workflow into export code.
   *
   * @param Workflow $workflow
   *   The workflow to export.
   * @param string $identifier
   *   The unique machine name for the workflow in the export.
   * @param array $code
   *   A reference to the export code array that will receive the output.
   */
  protected function export_render_workflow(Workflow $workflow, $identifier, array &$code) {

    // Make sure data is not copied to the database.
    $workflow = clone $workflow;
    $this
      ->sanitize_workflow_for_export($workflow);

    // Make sure to escape the characters \ and '.
    // The following method has the advantage, that you can export with
    // features,
    // and later import without enabling Features in the target system.
    $workflow_export = addcslashes(entity_export($this->type, $workflow, '  '), '\\\'');
    $workflow_identifier = features_var_export($identifier);
    $code[] = "  // Exported workflow: {$workflow_identifier}";
    $code[] = "  \$workflows[{$workflow_identifier}] = entity_import('{$this->type}', '" . $workflow_export . "');";
    $code[] = '';

    // Blank line
  }

  /**
   * Prepares the provided workflow for export.
   *
   * Removes serial IDs and replaces them with machine names.
   *
   * @param Workflow $workflow
   *   The workflow to sanitize. The contents of this object are modified directly.
   */
  protected function sanitize_workflow_for_export(Workflow $workflow) {

    // Eliminate serial IDs in exports to prevent "Overridden" status.
    // We use machine names instead.
    unset($workflow->wid);

    // Add roles to translate role IDs on target system.
    $permission = NULL;

    // Get system roles.
    $workflow->system_roles = workflow_get_roles($permission);

    // Only export system roles for roles used by this workflow.
    $roles = array();
    foreach ($workflow->transitions as $id => $transition) {
      foreach ($transition->roles as $rid) {
        $roles[] = $rid;
      }
    }
    $roles = array_unique($roles);
    foreach ($workflow->system_roles as $id => $system_role) {
      if (!in_array($id, $roles)) {
        unset($workflow->system_roles[$id]);
      }
    }
    $sid_to_name_map = $this
      ->pack_states($workflow);
    $this
      ->pack_transitions($workflow, $sid_to_name_map);
  }

  /**
   * "Packs" the states in the provided workflow into an export-friendly format.
   *
   * @param Workflow $workflow
   *   The workflow to pack. The contents of this object are modified directly.
   *
   * @return array
   *   A map of the old state IDs to their new machine names.
   */
  protected function pack_states(Workflow $workflow) {
    $named_states = array();
    $sid_to_name_map = array();
    foreach ($workflow->states as $state) {

      /* @var WorkflowState $state */
      $name = $state
        ->getName();
      $sid_to_name_map[$state->sid] = $name;

      // Eliminate serial IDs in exports to prevent "Overridden" status.
      // We use machine names instead.
      unset($state->sid);
      unset($state->wid);
      $named_states[$name] = $state;
    }
    ksort($named_states);

    // Identify states by machine name.
    $workflow->states = $named_states;
    return $sid_to_name_map;
  }

  /**
   * "Packs" the transitions in the provided workflow into an export-friendly format.
   *
   * @param Workflow $workflow
   *   The workflow to pack. The contents of this object are modified directly.
   *
   * @param array $sid_to_name_map
   *   The map of numeric state IDs to their machine names, for remapping sid
   *   references.
   */
  protected function pack_transitions(Workflow $workflow, array $sid_to_name_map) {
    $named_transitions = array();
    foreach ($workflow->transitions as $transition) {

      /* @var WorkflowTransition $transition */
      $start_name = $sid_to_name_map[$transition->sid];
      $end_name = $sid_to_name_map[$transition->target_sid];
      $new_name = WorkflowConfigTransition::machineName($start_name, $end_name);
      $transition->name = $new_name;
      $transition->start_state = $start_name;
      $transition->end_state = $end_name;

      // Eliminate serial IDs in exports to prevent "Overridden" status.
      // We use machine names instead.
      unset($transition->wid);
      unset($transition->tid);
      unset($transition->sid);
      unset($transition->target_sid);
      $named_transitions[$new_name] = $transition;
    }
    ksort($named_transitions);

    // Identify transitions by new machine name.
    $workflow->transitions = $named_transitions;
  }

  /**
   * Revert this workflow, either creating the workflow new (if one with the
   * same machine name is not present), or updating the existing workflow.
   *
   * @param string $module
   *   The name of the feature module whose components should be reverted.
   */
  function revert($module = NULL) {

    // Loads defaults from feature code.
    $defaults = workflow_get_defaults($module);
    if (!empty($defaults)) {
      foreach ($defaults as $machine_name => $entity) {
        workflow_revert($defaults, $machine_name);
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
EntityDefaultFeaturesController::$type protected property
EntityDefaultFeaturesController::api public function Defines the result for hook_features_api().
EntityDefaultFeaturesController::export_options public function Generates the result for hook_features_export_options().
EntityDefaultFeaturesController::__construct public function
WorkflowFeaturesController::export public function Generates the result for hook_features_export(). Overrides EntityDefaultFeaturesController::export
WorkflowFeaturesController::export_render public function Generates the result for hook_features_export_render(). Overrides EntityDefaultFeaturesController::export_render
WorkflowFeaturesController::export_render_workflow protected function Renders the provided workflow into export code.
WorkflowFeaturesController::pack_states protected function "Packs" the states in the provided workflow into an export-friendly format.
WorkflowFeaturesController::pack_transitions protected function "Packs" the transitions in the provided workflow into an export-friendly format.
WorkflowFeaturesController::revert function Revert this workflow, either creating the workflow new (if one with the same machine name is not present), or updating the existing workflow. Overrides EntityDefaultFeaturesController::revert
WorkflowFeaturesController::sanitize_workflow_for_export protected function Prepares the provided workflow for export.