You are here

class WebformNodeReferencesListController in Webform 8.5

Same name and namespace in other branches
  1. 6.x modules/webform_node/src/Controller/WebformNodeReferencesListController.php \Drupal\webform_node\Controller\WebformNodeReferencesListController

Defines a controller for webform node references.

Even though this is controller we are extending EntityListBuilder because the it's interface and patterns are application for display webform node references.

Hierarchy

Expanded class hierarchy of WebformNodeReferencesListController

File

modules/webform_node/src/Controller/WebformNodeReferencesListController.php, line 28

Namespace

Drupal\webform_node\Controller
View source
class WebformNodeReferencesListController extends EntityListBuilder implements ContainerInjectionInterface {

  /**
   * The date formatter service.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * The webform submission storage.
   *
   * @var \Drupal\webform\WebformSubmissionStorageInterface
   */
  protected $submissionStorage;

  /**
   * The node type storage.
   *
   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
   */
  protected $nodeTypeStorage;

  /**
   * The field config storage.
   *
   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
   */
  protected $fieldConfigStorage;

  /**
   * The webform entity reference manager.
   *
   * @var \Drupal\webform\WebformEntityReferenceManagerInterface
   */
  protected $webformEntityReferenceManager;

  /**
   * The webform.
   *
   * @var \Drupal\webform\WebformInterface
   */
  protected $webform;

  /**
   * Webform node field names.
   *
   * @var array
   */
  protected $fieldNames;

  /**
   * Webform node type.
   *
   * @var array
   */
  protected $nodeTypes;

  /**
   * Provides the listing page for webform node references.
   *
   * @return array
   *   A render array as expected by drupal_render().
   */
  public function listing(WebformInterface $webform) {
    $this->webform = $webform;
    if (empty($this->fieldNames)) {
      return [
        '#type' => 'webform_message',
        '#message_type' => 'warning',
        '#message_message' => $this
          ->t('There are no nodes with webform entity references. Please create add a Webform field to content type.'),
      ];
    }
    else {
      return $this
        ->render();
    }
  }

  /**
   * Constructs a new WebformNodeReferencesListController object.
   *
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition.
   * @param \Drupal\Core\Entity\EntityStorageInterface $storage
   *   The entity storage class.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter service.
   * @param \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $node_type_storage
   *   The node type storage class.
   * @param \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $field_config_storage
   *   The field config storage class.
   * @param \Drupal\webform\WebformSubmissionStorageInterface $webform_submission_storage
   *   The webform submission storage class.
   * @param \Drupal\webform\WebformEntityReferenceManagerInterface $webform_entity_reference_manager
   *   The webform entity reference manager.
   */
  public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, DateFormatterInterface $date_formatter, ConfigEntityStorageInterface $node_type_storage, ConfigEntityStorageInterface $field_config_storage, WebformSubmissionStorageInterface $webform_submission_storage, WebformEntityReferenceManagerInterface $webform_entity_reference_manager) {
    parent::__construct($entity_type, $storage);
    $this->dateFormatter = $date_formatter;
    $this->nodeTypeStorage = $node_type_storage;
    $this->fieldConfigStorage = $field_config_storage;
    $this->submissionStorage = $webform_submission_storage;
    $this->webformEntityReferenceManager = $webform_entity_reference_manager;
    $this->nodeTypes = [];
    $this->fieldNames = [];

    /** @var \Drupal\node\Entity\NodeType[] $node_types */
    $node_types = $this->nodeTypeStorage
      ->loadMultiple();

    /** @var \Drupal\field\FieldConfigInterface[] $field_configs */
    $field_configs = $this->fieldConfigStorage
      ->loadByProperties([
      'entity_type' => 'node',
    ]);
    foreach ($field_configs as $field_config) {
      if ($field_config
        ->get('field_type') === 'webform') {
        $bundle = $field_config
          ->get('bundle');
        $this->nodeTypes[$bundle] = $node_types[$bundle];
        $field_name = $field_config
          ->get('field_name');
        $this->fieldNames[$field_name] = $field_name;
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('entity_type.manager')
      ->getDefinition('node'), $container
      ->get('entity_type.manager')
      ->getStorage('node'), $container
      ->get('date.formatter'), $container
      ->get('entity_type.manager')
      ->getStorage('node_type'), $container
      ->get('entity_type.manager')
      ->getStorage('field_config'), $container
      ->get('entity_type.manager')
      ->getStorage('webform_submission'), $container
      ->get('webform.entity_reference_manager'));
  }

  /**
   * {@inheritdoc}
   */
  public function buildHeader() {
    $webform = $this->webform;
    $header = [];
    $header['title'] = $this
      ->t('Title');
    $header['type'] = [
      'data' => $this
        ->t('Type'),
      'class' => [
        RESPONSIVE_PRIORITY_MEDIUM,
      ],
    ];
    if ($webform
      ->hasVariants()) {
      $element_keys = $webform
        ->getElementsVariant();
      foreach ($element_keys as $element_key) {
        $element = $webform
          ->getElement($element_key);
        $header['element__' . $element_key] = [
          'data' => WebformElementHelper::getAdminTitle($element),
          'class' => [
            RESPONSIVE_PRIORITY_LOW,
          ],
        ];
      }
    }
    $header['author'] = [
      'data' => $this
        ->t('Author'),
      'class' => [
        RESPONSIVE_PRIORITY_LOW,
      ],
    ];
    $header['changed'] = [
      'data' => $this
        ->t('Updated'),
      'class' => [
        RESPONSIVE_PRIORITY_LOW,
      ],
    ];
    $header['node_status'] = [
      'data' => $this
        ->t('Node status'),
      'class' => [
        RESPONSIVE_PRIORITY_LOW,
      ],
    ];
    $header['webform_status'] = [
      'data' => $this
        ->t('Webform status'),
      'class' => [
        RESPONSIVE_PRIORITY_LOW,
      ],
    ];
    $header['results'] = [
      'data' => $this
        ->t('Results'),
      'class' => [
        RESPONSIVE_PRIORITY_MEDIUM,
      ],
    ];
    return $header + parent::buildHeader();
  }

  /**
   * {@inheritdoc}
   */
  public function buildRow(EntityInterface $entity) {
    $webform = $this->webform;

    /** @var \Drupal\node\NodeInterface $entity */
    $row['title']['data'] = [
      '#type' => 'link',
      '#title' => $entity
        ->label(),
      '#url' => $entity
        ->toUrl(),
    ];
    $row['type'] = node_get_type_label($entity);
    if ($webform
      ->hasVariants()) {
      $variant_element_keys = $webform
        ->getElementsVariant();
      foreach ($variant_element_keys as $variant_element_key) {
        $variants = [];
        foreach ($this->fieldNames as $field_name) {
          if (!$entity
            ->hasField($field_name)) {
            continue;
          }
          $default_data = Yaml::decode($entity->{$field_name}->default_data);
          if (empty($default_data[$variant_element_key])) {
            continue;
          }
          $variant_instance_id = $default_data[$variant_element_key];
          if ($webform
            ->getVariants()
            ->has($variant_instance_id)) {
            $variant_plugin = $webform
              ->getVariant($variant_instance_id);
            $variants[$default_data[$variant_element_key]] = $variant_plugin
              ->label();
          }
        }
        $row['element__' . $variant_element_key] = [
          'data' => implode('; ', $variants),
          'class' => [
            RESPONSIVE_PRIORITY_LOW,
          ],
        ];
      }
    }
    $row['author']['data'] = [
      '#theme' => 'username',
      '#account' => $entity
        ->getOwner(),
    ];
    $row['changed'] = $this->dateFormatter
      ->format($entity
      ->getChangedTime(), 'short');
    $row['node_status'] = $entity
      ->isPublished() ? $this
      ->t('Published') : $this
      ->t('Not published');
    $row['webform_status'] = $this
      ->getWebformStatus($entity);
    $result_total = $this->submissionStorage
      ->getTotal($this->webform, $entity);
    $results_access = $entity
      ->access('submission_view_any');
    $results_disabled = $this->webform
      ->isResultsDisabled();
    if ($results_disabled || !$results_access) {
      $row['results'] = $result_total;
    }
    else {
      $route_parameters = [
        'node' => $entity
          ->id(),
      ];
      $row['results'] = [
        'data' => [
          '#type' => 'link',
          '#title' => $result_total,
          '#attributes' => [
            'aria-label' => $this
              ->formatPlural($result_total, '@count result for @label', '@count results for @label', [
              '@label' => $entity
                ->label(),
            ]),
          ],
          '#url' => Url::fromRoute('entity.node.webform.results_submissions', $route_parameters),
        ],
      ];
    }
    $row['operations']['data'] = $this
      ->buildOperations($entity);
    return $row + parent::buildRow($entity);
  }

  /**
   * Get the webform node's status.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The node.
   *
   * @return \Drupal\Core\StringTranslation\TranslatableMarkup|null
   *   The webform node status.
   *
   * @see \Drupal\webform\Plugin\Field\FieldFormatter\WebformEntityReferenceFormatterBase::isOpen
   */
  protected function getWebformStatus(EntityInterface $entity) {

    // Get source entity's webform field.
    $webform_field_name = $this->webformEntityReferenceManager
      ->getFieldName($entity);
    if (!$webform_field_name) {
      return NULL;
    }
    if ($entity->{$webform_field_name}->target_id !== $this->webform
      ->id()) {
      return NULL;
    }
    $webform_field = $entity->{$webform_field_name};
    if ($webform_field->status === WebformInterface::STATUS_OPEN) {
      return $this
        ->t('Open');
    }
    if ($webform_field->status === WebformInterface::STATUS_SCHEDULED) {
      $is_opened = TRUE;
      if ($webform_field->open && strtotime($webform_field->open) > time()) {
        $is_opened = FALSE;
      }
      $is_closed = FALSE;
      if ($webform_field->close && strtotime($webform_field->close) < time()) {
        $is_closed = TRUE;
      }
      return $is_opened && !$is_closed ? $this
        ->t('Open') : $this
        ->t('Closed');
    }
    return $this
      ->t('Closed');
  }

  /**
   * {@inheritdoc}
   */
  public function buildOperations(EntityInterface $entity) {
    $build = [
      '#type' => 'operations',
      '#links' => $this
        ->getOperations($entity),
      '#prefix' => '<div class="webform-dropbutton">',
      '#suffix' => '</div>',
    ];
    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function getDefaultOperations(EntityInterface $entity) {
    $route_parameters = [
      'node' => $entity
        ->id(),
    ];
    $operations = [];
    if ($entity
      ->access('update')) {
      $operations['edit'] = [
        'title' => $this
          ->t('Edit'),
        'url' => $this
          ->ensureDestination($entity
          ->toUrl('edit-form')),
      ];
    }
    if ($entity
      ->access('view')) {
      $operations['view'] = [
        'title' => $this
          ->t('View'),
        'url' => $this
          ->ensureDestination($entity
          ->toUrl('canonical')),
      ];
    }
    if ($entity
      ->access('submission_view_any') && !$this->webform
      ->isResultsDisabled()) {
      $operations['results'] = [
        'title' => $this
          ->t('Results'),
        'url' => Url::fromRoute('entity.node.webform.results_submissions', $route_parameters),
      ];
    }
    if ($entity
      ->access('update') && $this->webform
      ->getSetting('share_node', TRUE) && $this
      ->moduleHandler()
      ->moduleExists('webform_share')) {
      $operations['share'] = [
        'title' => $this
          ->t('Share'),
        'url' => Url::fromRoute('entity.node.webform.share_embed', $route_parameters),
      ];
    }
    if ($entity
      ->access('delete')) {
      $operations['delete'] = [
        'title' => $this
          ->t('Delete'),
        'url' => $this
          ->ensureDestination($entity
          ->toUrl('delete-form')),
      ];
    }
    return $operations;
  }

  /**
   * {@inheritdoc}
   */
  public function render() {
    $build = [];
    $build['info'] = $this
      ->buildInfo();
    $build += parent::render();
    $build['table']['#sticky'] = TRUE;

    // Customize the empty message.
    $build['table']['#empty'] = $this
      ->t('There are no webform node references.');

    // Must manually add local actions because we can't alter local actions and
    // add query string parameter.
    // @see https://www.drupal.org/node/2585169
    $local_actions = [];
    if ($this->webform
      ->hasVariants()) {
      foreach ($this->nodeTypes as $bundle => $node_type) {
        if ($node_type
          ->access('create')) {
          $local_actions['webform_node.references.add_form'] = [
            '#theme' => 'menu_local_action',
            '#link' => [
              'title' => $this
                ->t('Add reference'),
              'url' => Url::fromRoute('entity.webform.references.add_form', [
                'webform' => $this->webform
                  ->id(),
              ]),
              'attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NARROW),
            ],
          ];
          WebformDialogHelper::attachLibraries($local_actions['webform_node.references.add_form']);
        }
      }
    }
    else {
      foreach ($this->nodeTypes as $bundle => $node_type) {
        if ($node_type
          ->access('create')) {
          $local_actions['webform_node.references.add_' . $bundle] = [
            '#theme' => 'menu_local_action',
            '#link' => [
              'title' => $this
                ->t('Add @title', [
                '@title' => $node_type
                  ->label(),
              ]),
              'url' => Url::fromRoute('node.add', [
                'node_type' => $bundle,
              ], [
                'query' => [
                  'webform_id' => $this->webform
                    ->id(),
                ],
              ]),
            ],
          ];
        }
      }
    }
    if ($local_actions) {
      $build['local_actions'] = [
        '#prefix' => '<ul class="action-links">',
        '#suffix' => '</ul>',
        '#weight' => -100,
      ] + $local_actions;
    }
    $build['#attached']['library'][] = 'webform_node/webform_node.references';
    return $build;
  }

  /**
   * Build information summary.
   *
   * @return array
   *   A render array representing the information summary.
   */
  protected function buildInfo() {
    $total = $this
      ->getTotal();
    return [
      '#markup' => $this
        ->formatPlural($total, '@count reference', '@count references'),
      '#prefix' => '<div>',
      '#suffix' => '</div>',
    ];
  }

  /**
   * {@inheritdoc}
   */
  protected function getEntityIds() {
    $query = $this
      ->getStorage()
      ->getQuery()
      ->sort($this->entityType
      ->getKey('id'));

    // Add field names.
    $or = $query
      ->orConditionGroup();
    foreach ($this->fieldNames as $field_name) {
      $or
        ->condition($field_name . '.target_id', $this->webform
        ->id());
    }
    $query
      ->condition($or);

    // Only add the pager if a limit is specified.
    if ($this->limit) {
      $query
        ->pager($this->limit);
    }
    return $query
      ->execute();
  }

  /**
   * Get the total number of references.
   *
   * @return int
   *   The total number of references.
   */
  protected function getTotal() {
    $query = $this
      ->getStorage()
      ->getQuery()
      ->sort($this->entityType
      ->getKey('id'));

    // Add field names.
    $or = $query
      ->orConditionGroup();
    foreach ($this->fieldNames as $field_name) {
      $or
        ->condition($field_name . '.target_id', $this->webform
        ->id());
    }
    $query
      ->condition($or);
    return count($query
      ->execute());
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
EntityHandlerBase::$moduleHandler protected property The module handler to invoke hooks on. 2
EntityHandlerBase::moduleHandler protected function Gets the module handler. 2
EntityHandlerBase::setModuleHandler public function Sets the module handler for this handler.
EntityListBuilder::$entityType protected property Information about the entity type.
EntityListBuilder::$entityTypeId protected property The entity type ID.
EntityListBuilder::$limit protected property The number of entities to list per page, or FALSE to list all entities. 3
EntityListBuilder::$storage protected property The entity storage class. 1
EntityListBuilder::createInstance public static function Instantiates a new instance of this entity handler. Overrides EntityHandlerInterface::createInstance 20
EntityListBuilder::ensureDestination protected function Ensures that a destination is present on the given URL.
EntityListBuilder::getLabel Deprecated protected function Gets the label of an entity.
EntityListBuilder::getOperations public function Provides an array of information to build a list of operation links. Overrides EntityListBuilderInterface::getOperations 2
EntityListBuilder::getStorage public function Gets the entity storage. Overrides EntityListBuilderInterface::getStorage
EntityListBuilder::getTitle protected function Gets the title of the page. 1
EntityListBuilder::load public function Loads entities of this type from storage for listing. Overrides EntityListBuilderInterface::load 4
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
WebformNodeReferencesListController::$dateFormatter protected property The date formatter service.
WebformNodeReferencesListController::$fieldConfigStorage protected property The field config storage.
WebformNodeReferencesListController::$fieldNames protected property Webform node field names.
WebformNodeReferencesListController::$nodeTypes protected property Webform node type.
WebformNodeReferencesListController::$nodeTypeStorage protected property The node type storage.
WebformNodeReferencesListController::$submissionStorage protected property The webform submission storage.
WebformNodeReferencesListController::$webform protected property The webform.
WebformNodeReferencesListController::$webformEntityReferenceManager protected property The webform entity reference manager.
WebformNodeReferencesListController::buildHeader public function Builds the header row for the entity listing. Overrides EntityListBuilder::buildHeader
WebformNodeReferencesListController::buildInfo protected function Build information summary.
WebformNodeReferencesListController::buildOperations public function Builds a renderable list of operation links for the entity. Overrides EntityListBuilder::buildOperations
WebformNodeReferencesListController::buildRow public function Builds a row for an entity in the entity listing. Overrides EntityListBuilder::buildRow
WebformNodeReferencesListController::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create
WebformNodeReferencesListController::getDefaultOperations public function Gets this list's default operations. Overrides EntityListBuilder::getDefaultOperations
WebformNodeReferencesListController::getEntityIds protected function Loads entity IDs using a pager sorted by the entity id. Overrides EntityListBuilder::getEntityIds
WebformNodeReferencesListController::getTotal protected function Get the total number of references.
WebformNodeReferencesListController::getWebformStatus protected function Get the webform node's status.
WebformNodeReferencesListController::listing public function Provides the listing page for webform node references.
WebformNodeReferencesListController::render public function Builds the entity listing as renderable array for table.html.twig. Overrides EntityListBuilder::render
WebformNodeReferencesListController::__construct public function Constructs a new WebformNodeReferencesListController object. Overrides EntityListBuilder::__construct