You are here

class ForumController in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/forum/src/Controller/ForumController.php \Drupal\forum\Controller\ForumController

Controller routines for forum routes.

Hierarchy

Expanded class hierarchy of ForumController

File

core/modules/forum/src/Controller/ForumController.php, line 22

Namespace

Drupal\forum\Controller
View source
class ForumController extends ControllerBase {

  /**
   * Forum manager service.
   *
   * @var \Drupal\forum\ForumManagerInterface
   */
  protected $forumManager;

  /**
   * Vocabulary storage.
   *
   * @var \Drupal\taxonomy\VocabularyStorageInterface
   */
  protected $vocabularyStorage;

  /**
   * Term storage.
   *
   * @var \Drupal\taxonomy\TermStorageInterface
   */
  protected $termStorage;

  /**
   * Node access control handler.
   *
   * @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface
   */
  protected $nodeAccess;

  /**
   * Field map of existing fields on the site.
   *
   * @var array
   */
  protected $fieldMap;

  /**
   * Node type storage handler.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $nodeTypeStorage;

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * Node entity type, we need to get cache tags from here.
   *
   * @var \Drupal\Core\Entity\EntityTypeInterface
   */
  protected $nodeEntityTypeDefinition;

  /**
   * Comment entity type, we need to get cache tags from here.
   *
   * @var \Drupal\Core\Entity\EntityTypeInterface
   */
  protected $commentEntityTypeDefinition;

  /**
   * Constructs a ForumController object.
   *
   * @param \Drupal\forum\ForumManagerInterface $forum_manager
   *   The forum manager service.
   * @param \Drupal\taxonomy\VocabularyStorageInterface $vocabulary_storage
   *   Vocabulary storage.
   * @param \Drupal\taxonomy\TermStorageInterface $term_storage
   *   Term storage.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current logged in user.
   * @param \Drupal\Core\Entity\EntityAccessControlHandlerInterface $node_access
   *   Node access control handler.
   * @param array $field_map
   *   Array of active fields on the site.
   * @param \Drupal\Core\Entity\EntityStorageInterface $node_type_storage
   *   Node type storage handler.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   * @param \Drupal\Core\Entity\EntityTypeInterface $node_entity_type_definition
   *   Node entity type definition object
   * @param \Drupal\Core\Entity\EntityTypeInterface $comment_entity_type_definition
   *   Comment entity type definition object
   */
  public function __construct(ForumManagerInterface $forum_manager, VocabularyStorageInterface $vocabulary_storage, TermStorageInterface $term_storage, AccountInterface $current_user, EntityAccessControlHandlerInterface $node_access, array $field_map, EntityStorageInterface $node_type_storage, RendererInterface $renderer, EntityTypeInterface $node_entity_type_definition, EntityTypeInterface $comment_entity_type_definition) {
    $this->forumManager = $forum_manager;
    $this->vocabularyStorage = $vocabulary_storage;
    $this->termStorage = $term_storage;
    $this->currentUser = $current_user;
    $this->nodeAccess = $node_access;
    $this->fieldMap = $field_map;
    $this->nodeTypeStorage = $node_type_storage;
    $this->renderer = $renderer;
    $this->nodeEntityTypeDefinition = $node_entity_type_definition;
    $this->commentEntityTypeDefinition = $comment_entity_type_definition;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {

    /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
    $entity_type_manager = $container
      ->get('entity_type.manager');
    return new static($container
      ->get('forum_manager'), $entity_type_manager
      ->getStorage('taxonomy_vocabulary'), $entity_type_manager
      ->getStorage('taxonomy_term'), $container
      ->get('current_user'), $entity_type_manager
      ->getAccessControlHandler('node'), $container
      ->get('entity_field.manager')
      ->getFieldMap(), $entity_type_manager
      ->getStorage('node_type'), $container
      ->get('renderer'), $entity_type_manager
      ->getDefinition('node'), $entity_type_manager
      ->getDefinition('comment'));
  }

  /**
   * Returns forum page for a given forum.
   *
   * @param \Drupal\taxonomy\TermInterface $taxonomy_term
   *   The forum to render the page for.
   *
   * @return array
   *   A render array.
   */
  public function forumPage(TermInterface $taxonomy_term) {

    // Get forum details.
    $taxonomy_term->forums = $this->forumManager
      ->getChildren($this
      ->config('forum.settings')
      ->get('vocabulary'), $taxonomy_term
      ->id());
    $taxonomy_term->parents = $this->termStorage
      ->loadAllParents($taxonomy_term
      ->id());
    if (empty($taxonomy_term->forum_container->value)) {
      $build = $this->forumManager
        ->getTopics($taxonomy_term
        ->id(), $this
        ->currentUser());
      $topics = $build['topics'];
      $header = $build['header'];
    }
    else {
      $topics = [];
      $header = [];
    }
    return $this
      ->build($taxonomy_term->forums, $taxonomy_term, $topics, $taxonomy_term->parents, $header);
  }

  /**
   * Returns forum index page.
   *
   * @return array
   *   A render array.
   */
  public function forumIndex() {
    $vocabulary = $this->vocabularyStorage
      ->load($this
      ->config('forum.settings')
      ->get('vocabulary'));
    $index = $this->forumManager
      ->getIndex();
    $build = $this
      ->build($index->forums, $index);
    if (empty($index->forums)) {

      // Root of empty forum.
      $build['#title'] = $this
        ->t('No forums defined');
    }
    else {

      // Set the page title to forum's vocabulary name.
      $build['#title'] = $vocabulary
        ->label();
      $this->renderer
        ->addCacheableDependency($build, $vocabulary);
    }
    return $build;
  }

  /**
   * Returns a renderable forum index page array.
   *
   * @param array $forums
   *   A list of forums.
   * @param \Drupal\taxonomy\TermInterface $term
   *   The taxonomy term of the forum.
   * @param array $topics
   *   The topics of this forum.
   * @param array $parents
   *   The parent forums in relation this forum.
   * @param array $header
   *   Array of header cells.
   *
   * @return array
   *   A render array.
   */
  protected function build($forums, TermInterface $term, $topics = [], $parents = [], $header = []) {
    $config = $this
      ->config('forum.settings');
    $build = [
      '#theme' => 'forums',
      '#forums' => $forums,
      '#topics' => $topics,
      '#parents' => $parents,
      '#header' => $header,
      '#term' => $term,
      '#sortby' => $config
        ->get('topics.order'),
      '#forums_per_page' => $config
        ->get('topics.page_limit'),
    ];
    if (empty($term->forum_container->value)) {
      $build['#attached']['feed'][] = [
        'taxonomy/term/' . $term
          ->id() . '/feed',
        'RSS - ' . $term
          ->getName(),
      ];
    }
    $this->renderer
      ->addCacheableDependency($build, $config);
    foreach ($forums as $forum) {
      $this->renderer
        ->addCacheableDependency($build, $forum);
    }
    foreach ($topics as $topic) {
      $this->renderer
        ->addCacheableDependency($build, $topic);
    }
    foreach ($parents as $parent) {
      $this->renderer
        ->addCacheableDependency($build, $parent);
    }
    $this->renderer
      ->addCacheableDependency($build, $term);
    $is_forum = empty($term->forum_container->value);
    return [
      'action' => $is_forum ? $this
        ->buildActionLinks($config
        ->get('vocabulary'), $term) : [],
      'forum' => $build,
      '#cache' => [
        'tags' => Cache::mergeTags($this->nodeEntityTypeDefinition
          ->getListCacheTags(), $this->commentEntityTypeDefinition
          ->getListCacheTags()),
      ],
    ];
  }

  /**
   * Returns add forum entity form.
   *
   * @return array
   *   Render array for the add form.
   */
  public function addForum() {
    $vid = $this
      ->config('forum.settings')
      ->get('vocabulary');
    $taxonomy_term = $this->termStorage
      ->create([
      'vid' => $vid,
      'forum_controller' => 0,
    ]);
    return $this
      ->entityFormBuilder()
      ->getForm($taxonomy_term, 'forum');
  }

  /**
   * Returns add container entity form.
   *
   * @return array
   *   Render array for the add form.
   */
  public function addContainer() {
    $vid = $this
      ->config('forum.settings')
      ->get('vocabulary');
    $taxonomy_term = $this->termStorage
      ->create([
      'vid' => $vid,
      'forum_container' => 1,
    ]);
    return $this
      ->entityFormBuilder()
      ->getForm($taxonomy_term, 'container');
  }

  /**
   * Generates an action link to display at the top of the forum listing.
   *
   * @param string $vid
   *   Vocabulary ID.
   * @param \Drupal\taxonomy\TermInterface $forum_term
   *   The term for which the links are to be built.
   *
   * @return array
   *   Render array containing the links.
   */
  protected function buildActionLinks($vid, TermInterface $forum_term = NULL) {
    $user = $this
      ->currentUser();
    $links = [];

    // Loop through all bundles for forum taxonomy vocabulary field.
    foreach ($this->fieldMap['node']['taxonomy_forums']['bundles'] as $type) {
      if ($this->nodeAccess
        ->createAccess($type)) {
        $node_type = $this->nodeTypeStorage
          ->load($type);
        $links[$type] = [
          '#theme' => 'menu_local_action',
          '#link' => [
            'title' => $this
              ->t('Add new @node_type', [
              '@node_type' => $this->nodeTypeStorage
                ->load($type)
                ->label(),
            ]),
            'url' => Url::fromRoute('node.add', [
              'node_type' => $type,
            ]),
          ],
          '#cache' => [
            'tags' => $node_type
              ->getCacheTags(),
          ],
        ];
        if ($forum_term && $forum_term
          ->bundle() == $vid) {

          // We are viewing a forum term (specific forum), append the tid to
          // the url.
          $links[$type]['#link']['localized_options']['query']['forum_id'] = $forum_term
            ->id();
        }
      }
    }
    if (empty($links)) {

      // Authenticated user does not have access to create new topics.
      if ($user
        ->isAuthenticated()) {
        $links['disallowed'] = [
          '#markup' => $this
            ->t('You are not allowed to post new content in the forum.'),
        ];
      }
      else {
        $links['login'] = [
          '#theme' => 'menu_local_action',
          '#link' => [
            'title' => $this
              ->t('Log in to post new content in the forum.'),
            'url' => Url::fromRoute('user.login', [], [
              'query' => $this
                ->getDestinationArray(),
            ]),
          ],
          // Without this workaround, the action links will be rendered as <li>
          // with no wrapping <ul> element.
          // @todo Find a better way for this in https://www.drupal.org/node/3181052.
          '#prefix' => '<ul class="action-links">',
          '#suffix' => '</ul>',
        ];
      }
    }
    else {

      // Without this workaround, the action links will be rendered as <li> with
      // no wrapping <ul> element.
      // @todo Find a better way for this in https://www.drupal.org/node/3181052.
      $links['#prefix'] = '<ul class="action-links">';
      $links['#suffix'] = '</ul>';
    }
    return $links;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ControllerBase::$configFactory protected property The configuration factory.
ControllerBase::$currentUser protected property The current user service. 1
ControllerBase::$entityFormBuilder protected property The entity form builder.
ControllerBase::$entityTypeManager protected property The entity type manager.
ControllerBase::$formBuilder protected property The form builder. 2
ControllerBase::$keyValue protected property The key-value storage. 1
ControllerBase::$languageManager protected property The language manager. 1
ControllerBase::$moduleHandler protected property The module handler. 2
ControllerBase::$stateService protected property The state service.
ControllerBase::cache protected function Returns the requested cache bin.
ControllerBase::config protected function Retrieves a configuration object.
ControllerBase::container private function Returns the service container.
ControllerBase::currentUser protected function Returns the current user. 1
ControllerBase::entityFormBuilder protected function Retrieves the entity form builder.
ControllerBase::entityTypeManager protected function Retrieves the entity type manager.
ControllerBase::formBuilder protected function Returns the form builder service. 2
ControllerBase::keyValue protected function Returns a key/value storage collection. 1
ControllerBase::languageManager protected function Returns the language manager service. 1
ControllerBase::moduleHandler protected function Returns the module handler. 2
ControllerBase::redirect protected function Returns a redirect response object for the specified route.
ControllerBase::state protected function Returns the state storage service.
ForumController::$commentEntityTypeDefinition protected property Comment entity type, we need to get cache tags from here.
ForumController::$fieldMap protected property Field map of existing fields on the site.
ForumController::$forumManager protected property Forum manager service.
ForumController::$nodeAccess protected property Node access control handler.
ForumController::$nodeEntityTypeDefinition protected property Node entity type, we need to get cache tags from here.
ForumController::$nodeTypeStorage protected property Node type storage handler.
ForumController::$renderer protected property The renderer.
ForumController::$termStorage protected property Term storage.
ForumController::$vocabularyStorage protected property Vocabulary storage.
ForumController::addContainer public function Returns add container entity form.
ForumController::addForum public function Returns add forum entity form.
ForumController::build protected function Returns a renderable forum index page array.
ForumController::buildActionLinks protected function Generates an action link to display at the top of the forum listing.
ForumController::create public static function Instantiates a new instance of this class. Overrides ControllerBase::create
ForumController::forumIndex public function Returns forum index page.
ForumController::forumPage public function Returns forum page for a given forum.
ForumController::__construct public function Constructs a ForumController object.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
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. 4
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.