You are here

public function FormsStepsProgressBarBlock::build in Forms Steps 8

Builds and returns the renderable array for this block plugin.

If a block should not be rendered because it has no content, then this method must also ensure to return no content: it must then only return an empty array, or an empty array with #cache set (with cacheability metadata indicating the circumstances for it being empty).

Return value

array A renderable array representing the content of the block.

Overrides BlockPluginInterface::build

See also

\Drupal\block\BlockViewBuilder

File

src/Plugin/Block/FormsStepsProgressBarBlock.php, line 104

Class

FormsStepsProgressBarBlock
Provides the progress bar block.

Namespace

Drupal\forms_steps\Plugin\Block

Code

public function build() {
  $route = $this->currentRouteMatch
    ->getRouteName();

  /** @var \Drupal\forms_steps\Step $step */
  $step = $this->formsStepsManager
    ->getStepByRoute($route);

  // The block is rendered only if the current route is a forms steps route.
  if ($step) {

    /** @var \Drupal\forms_steps\FormsStepsInterface $forms_steps */
    $forms_steps = $step
      ->formsSteps();

    // If the derivative id is the current step, we display
    // the corresponding progress steps.
    if ($forms_steps
      ->id() === $this->derivativeId) {
      $items = [];
      $item_class = 'previous-step';

      // Retrieve current workflow instance_id to add it to the link.
      $instanceId = $this->formsStepsHelper
        ->getWorkflowInstanceIdFromRoute();
      $saved_steps = $this->workflowRepository
        ->load([
        'instance_id' => $instanceId,
      ]);
      foreach ($forms_steps
        ->getProgressSteps() as $progress_step) {
        $item = [];

        // Prepare the current progress step content regarding
        // the existence of a link and its visibility configuration.
        $link_visibility = array_filter($progress_step
          ->linkVisibility());
        if ($forms_steps
          ->getProgressStepsLinksSavedOnly() && !empty($saved_steps)) {
          $saved_steps_flat = [];
          foreach ($saved_steps as $saved_step) {
            $saved_steps_flat[$saved_step->step] = $saved_step->step;
          }
          if ($forms_steps
            ->getProgressStepsLinksSavedOnlyNext()) {
            $saved_step_last = end($saved_steps);
            $saved_step_last_entity = $forms_steps
              ->getStep($saved_step_last->step);
            $saved_step_next = $forms_steps
              ->getNextStep($saved_step_last_entity);
            if ($saved_step_next) {
              $saved_steps_flat[$saved_step_next
                ->id()] = $saved_step_next
                ->id();
            }
          }
          $link_visibility_check = !in_array($progress_step
            ->link(), $saved_steps_flat);
        }
        else {
          $link_visibility_check = !in_array($step
            ->id(), $link_visibility);
        }

        // Display a simple label or the link.
        // @todo: Manage the specific case of "No workflow instance id" for the first step to avoid having no links at all on this step.
        //          if (empty($progress_step->link()) || $link_visibility_check || empty($instanceId)) {
        if (empty($progress_step
          ->link()) || $link_visibility_check || empty($instanceId)) {
          $item['#markup'] = $this
            ->t($progress_step
            ->label());
        }
        else {
          $link_step = $forms_steps
            ->getStep($progress_step
            ->link());
          $options = [];
          if ($instanceId) {
            $options['instance_id'] = $instanceId;
          }
          $url = Url::fromRoute($forms_steps
            ->getStepRoute($link_step), $options);
          $link = Link::fromTextAndUrl($this
            ->t($progress_step
            ->label()), $url);
          $toRenderable = $link
            ->toRenderable();
          $markup = \Drupal::service('renderer')
            ->renderPlain($toRenderable);
          $item['#markup'] = $markup
            ->__toString();
        }
        $routes = $progress_step
          ->activeRoutes();
        array_filter($routes);

        // Defined the active status.
        $active = FALSE;
        foreach ($routes as $route) {
          if ($route === $step
            ->id()) {
            $active = TRUE;
            break;
          }
        }

        // Set classes.
        if ($active) {
          $item['#wrapper_attributes']['class'][] = 'active';
          $item_class = 'next-step';
        }
        else {
          $item['#wrapper_attributes']['class'][] = $item_class;
        }

        // Add item to the items list.
        $items[] = $item;
      }
      return [
        '#theme' => [
          'item_list__forms_steps',
          'item_list',
        ],
        '#list_type' => 'ol',
        '#title' => '',
        '#items' => $items,
        '#cache' => [
          'max-age' => 0,
        ],
      ];
    }
  }
  return [];
}