View source  
  <?php
namespace Drupal\webform;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityViewBuilder;
use Drupal\webform\Plugin\WebformElementAttachmentInterface;
use Drupal\webform\Plugin\WebformElementCompositeInterface;
use Drupal\webform\Twig\WebformTwigExtension;
use Drupal\webform\Utility\WebformElementHelper;
use Drupal\webform\Utility\WebformYaml;
use Symfony\Component\DependencyInjection\ContainerInterface;
class WebformSubmissionViewBuilder extends EntityViewBuilder implements WebformSubmissionViewBuilderInterface {
  
  protected $routeMatch;
  
  protected $requestHandler;
  
  protected $elementManager;
  
  protected $conditionsValidator;
  
  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
    $instance = parent::createInstance($container, $entity_type);
    $instance->requestHandler = $container
      ->get('webform.request');
    $instance->elementManager = $container
      ->get('plugin.manager.webform.element');
    $instance->conditionsValidator = $container
      ->get('webform_submission.conditions_validator');
    $instance->routeMatch = $container
      ->get('current_route_match');
    return $instance;
  }
  
  public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
    
    if ($webform_submissions_view_mode = \Drupal::request()->request
      ->get('_webform_submissions_view_mode')) {
      $view_mode = $webform_submissions_view_mode;
    }
    
    
    
    $webform = $entity
      ->getWebform();
    $webform
      ->applyVariants($entity);
    return parent::view($entity, $view_mode, $langcode);
  }
  
  protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
    $build = parent::getBuildDefaults($entity, $view_mode);
    
    $build['#theme'] = 'webform_submission_data';
    return $build;
  }
  
  public function buildComponents(array &$build, array $entities, array $displays, $view_mode) {
    if (empty($entities)) {
      return;
    }
    
    foreach ($entities as $id => $webform_submission) {
      $webform = $webform_submission
        ->getWebform();
      if ($view_mode === 'preview') {
        $options = [
          'view_mode' => $view_mode,
          'excluded_elements' => $webform
            ->getSetting('preview_excluded_elements'),
          'exclude_empty' => $webform
            ->getSetting('preview_exclude_empty'),
          'exclude_empty_checkbox' => $webform
            ->getSetting('preview_exclude_empty_checkbox'),
        ];
      }
      else {
        
        $route_name = $this->routeMatch
          ->getRouteName();
        $pdf = in_array($route_name, [
          'entity_print.view.debug',
          'entity_print.view',
        ]) || \Drupal::request()->request
          ->get('_webform_entity_print');
        $options = [
          'view_mode' => $view_mode,
          'excluded_elements' => $webform
            ->getSetting('submission_excluded_elements'),
          'exclude_empty' => $webform
            ->getSetting('submission_exclude_empty'),
          'exclude_empty_checkbox' => $webform
            ->getSetting('submission_exclude_empty_checkbox'),
          'pdf' => $pdf,
        ];
      }
      switch ($view_mode) {
        case 'twig':
          
          $build[$id]['data'] = WebformTwigExtension::buildTwigTemplate($webform_submission, $webform_submission->_webform_view_mode_twig);
          break;
        case 'yaml':
          
          $data = $webform_submission
            ->toArray(TRUE, TRUE);
          
          WebformElementHelper::convertRenderMarkupToStrings($data);
          $build[$id]['data'] = [
            '#theme' => 'webform_codemirror',
            '#code' => WebformYaml::encode($data),
            '#type' => 'yaml',
          ];
          break;
        case 'text':
          $elements = $webform
            ->getElementsInitialized();
          $build[$id]['data'] = [
            '#theme' => 'webform_codemirror',
            '#code' => $this
              ->buildElements($elements, $webform_submission, $options, 'text'),
          ];
          break;
        case 'table':
          $elements = $webform
            ->getElementsInitializedFlattenedAndHasValue();
          $build[$id]['data'] = $this
            ->buildTable($elements, $webform_submission, $options);
          break;
        default:
        case 'html':
          $elements = $webform
            ->getElementsInitialized();
          $build[$id]['data'] = $this
            ->buildElements($elements, $webform_submission, $options);
          break;
      }
    }
    parent::buildComponents($build, $entities, $displays, $view_mode);
  }
  
  public function buildElements(array $elements, WebformSubmissionInterface $webform_submission, array $options = [], $format = 'html') {
    $build_method = 'build' . ucfirst($format);
    $build = [];
    foreach ($elements as $key => $element) {
      if (!WebformElementHelper::isElement($element, $key)) {
        continue;
      }
      
      $webform_element = $this->elementManager
        ->getElementInstance($element);
      
      $webform_element
        ->replaceTokens($element, $webform_submission);
      if ($build_element = $webform_element
        ->{$build_method}($element, $webform_submission, $options)) {
        $build[$key] = $build_element;
        if (!$this
          ->isElementVisible($element, $webform_submission, $options)) {
          $build[$key]['#access'] = FALSE;
        }
      }
    }
    return $build;
  }
  
  public function buildTable(array $elements, WebformSubmissionInterface $webform_submission, array $options = []) {
    $rows = [];
    foreach ($elements as $key => $element) {
      if (!$this
        ->isElementVisible($element, $webform_submission, $options)) {
        continue;
      }
      
      $webform_element = $this->elementManager
        ->getElementInstance($element);
      
      $webform_element
        ->replaceTokens($element, $webform_submission);
      
      if ($webform_element
        ->isEmptyExcluded($element, $options) && !$webform_element
        ->getValue($element, $webform_submission, $options)) {
        continue;
      }
      $title = $element['#admin_title'] ?: $element['#title'] ?: '(' . $key . ')';
      
      $html = $webform_element
        ->formatHtml($element, $webform_submission, $options);
      $rows[$key] = [
        [
          'header' => TRUE,
          'data' => $title,
        ],
        [
          'data' => is_string($html) ? [
            '#markup' => $html,
          ] : $html,
        ],
      ];
    }
    return [
      '#type' => 'table',
      '#rows' => $rows,
      '#attributes' => [
        'class' => [
          'webform-submission-table',
        ],
      ],
    ];
  }
  
  protected function isElementVisible(array $element, WebformSubmissionInterface $webform_submission, array $options) {
    
    if (isset($element['#webform_key']) && isset($options['excluded_elements'][$element['#webform_key']])) {
      return FALSE;
    }
    
    if (!empty($options['exclude_attachments'])) {
      
      $webform_element = $this->elementManager
        ->getElementInstance($element, $webform_submission);
      if ($webform_element instanceof WebformElementAttachmentInterface && !$webform_element instanceof WebformElementCompositeInterface) {
        return FALSE;
      }
    }
    
    if (!$this->conditionsValidator
      ->isElementVisible($element, $webform_submission)) {
      return FALSE;
    }
    
    if (!empty($options['ignore_access'])) {
      return TRUE;
    }
    
    if (isset($element['#access']) && ($element['#access'] instanceof AccessResultInterface && $element['#access']
      ->isForbidden() || $element['#access'] === FALSE)) {
      return FALSE;
    }
    
    
    $webform_element = $this->elementManager
      ->getElementInstance($element, $webform_submission);
    return $webform_element
      ->checkAccessRules('view', $element) ? TRUE : FALSE;
  }
}