You are here

social_topic.module in Open Social 8.7

The Social topic module.

File

modules/social_features/social_topic/social_topic.module
View source
<?php

/**
 * @file
 * The Social topic module.
 */
use Drupal\block\Entity\Block;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultNeutral;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\social_topic\Controller\SocialTopicController;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;
use Drupal\Core\Language\LanguageInterface;

/**
 * Prepares variables for node templates.
 *
 * Default template: node.html.twig.
 *
 * Most themes use their own copy of node.html.twig. The default is located
 * inside "/core/modules/node/templates/node.html.twig". Look in there for the
 * full list of variables.
 *
 * @param array $variables
 *   An associative array containing:
 *   - elements: An array of elements to display in view mode.
 *   - node: The node object.
 *   - view_mode: View mode; e.g., 'full', 'teaser', etc.
 */
function social_topic_preprocess_node(array &$variables) {

  /* @var \Drupal\node\NodeInterface $node */
  $node = $variables['node'];
  if ($node
    ->getType() === 'topic') {
    $topic_type = $node
      ->get('field_topic_type');
    $topic_type_entities = $topic_type
      ->referencedEntities();
    if (count($topic_type_entities) === 1) {
      $curr_langcode = \Drupal::languageManager()
        ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
        ->getId();
      foreach ($topic_type_entities as $topic) {
        if ($topic
          ->isTranslatable() && $topic
          ->hasTranslation($curr_langcode)) {
          $topic = $topic
            ->getTranslation($curr_langcode);
        }
        $variables['metadata'] = t('in @topic', [
          '@topic' => $topic
            ->link(),
        ]);

        // Set topic type link.
        $topic_type_url = Url::fromRoute('view.latest_topics.page_latest_topics', [
          'field_topic_type_target_id' => $topic
            ->id(),
        ]);
        $topic_type_link = Link::fromTextAndUrl($topic
          ->label(), $topic_type_url)
          ->toString();
        $variables['topic_type'] = $topic_type_link;
      }
    }
    else {
      $variables['metadata'] = NULL;
      $variables['topic_type'] = NULL;
    }
  }
}

/**
 * Implements hook_form_form_ID_alter().
 *
 * Enhance the exposed filter form of the topic overview.
 */
function social_topic_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // On user topics overview.
  if ($form['#id'] === 'views-exposed-form-topics-page-profile') {
    $form['type']['#options']['All'] = t('All types');
    $form['status']['#options'][0] = t('Unpublished');
    $form['status']['#options'][1] = t('Published');
    $account_uid = \Drupal::routeMatch()
      ->getParameter('user');
    $current_uid = \Drupal::currentUser()
      ->id();
    if ($account_uid !== $current_uid) {
      $form['status']['#access'] = FALSE;
    }

    // Enable the reset button.
    // @todo make sure the block content refreshes on submit as well (AJAX).
    $form['actions']['reset']['#access'] = TRUE;

    // @todo make sure exposed form filtering redirects to the proper view
    // page, when views is updated.
    $form['#action'] = '/user/' . $account_uid . '/topics';
  }

  // On group topics overview.
  if ($form['#id'] === 'views-exposed-form-group-topics-page-group-topics') {
    $group_from_route = _social_group_get_current_group();
    $current_user = \Drupal::currentUser();
    $membership = FALSE;
    $group_membership = $group_from_route
      ->getMember($current_user);
    if ($group_membership) {
      $membership = TRUE;
    }
    if (!empty($form['status'])) {
      $form['status']['#options']['All'] = t('All statuses');
      $form['status']['#options'][0] = t('Unpublished');
      $form['status']['#options'][1] = t('Published');

      // Only show the unpublished option when you are member of the group.
      // You can't place content in a group you are not a member of anyway.
      if (!$membership) {
        $form['status']['#access'] = FALSE;
      }
    }
    $form['type']['#options']['All'] = t('All types');

    // Get group from route.
    if (!empty($group_from_route)) {
      $group_id = $group_from_route
        ->id();
    }
    $form['actions']['reset']['#access'] = TRUE;

    // Make sure we redirect to the current group page.
    $form['#action'] = '/group/' . $group_id . '/topics';
  }
}

/**
 * Implements hook_block_view_alter().
 *
 * Add a title to the exposed filter block on the topics overview.
 */
function social_topic_block_view_alter(array &$build, BlockPluginInterface $block) {

  // @todo check out why this happens, is this is a views bug?
  if (isset($build['#plugin_id']) && $build['#plugin_id'] === 'views_exposed_filter_block:topics-page_profile') {
    $build['#configuration']['label'] = $build['#configuration']['views_label'];
  }
}

/**
 * Implements hook_views_query_alter().
 */
function social_topic_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view
    ->id() == 'topics' && $view
    ->getDisplay()->display['id'] == 'page_profile') {
    $account_uid = \Drupal::routeMatch()
      ->getParameter('user');
    $current_uid = \Drupal::currentUser()
      ->id();
    if ($view->exposed_raw_input['status'] == NODE_PUBLISHED || $account_uid !== $current_uid) {
      $query->where[1]['conditions'][] = [
        'field' => 'node_field_data.status',
        'value' => NODE_PUBLISHED,
        'operator' => '=',
      ];
    }
  }

  // Only show the unpublished option when you are member of the group.
  // You can't place content in a group you are not a member of anyway.
  if ($view
    ->id() == 'group_topics' && $view
    ->getDisplay()->display['id'] == 'page_group_topics') {
    $group_from_route = _social_group_get_current_group();
    $current_user = \Drupal::currentUser();
    $membership = FALSE;
    $group_membership = $group_from_route
      ->getMember($current_user);
    if ($group_membership) {
      $membership = TRUE;
    }

    // Needs 1 and NODE_PUBLISHED, because it can be TRUE ( default ) or "1"
    // (see form alter when published is selected).
    if ($view->exposed_raw_input['status'] == "1" || $view->exposed_raw_input['status'] == NODE_PUBLISHED || !$membership) {
      $query->where[1]['conditions'][] = [
        'field' => 'node_field_data_group_content_field_data.status',
        'value' => NODE_PUBLISHED,
        'operator' => '=',
      ];
    }
  }
}

/**
 * Implements hook_social_user_account_header_create_links().
 *
 * Adds the "Create Topic" link to the content creation menu.
 */
function social_topic_social_user_account_header_create_links($context) {
  return [
    'add_topic' => [
      '#type' => 'link',
      '#attributes' => [
        'title' => new TranslatableMarkup('Create New Topic'),
      ],
      '#title' => new TranslatableMarkup('New Topic'),
      '#weight' => 200,
    ] + Url::fromRoute('node.add', [
      'node_type' => 'topic',
    ])
      ->toRenderArray(),
  ];
}

/**
 * Implements hook_social_user_account_header_account_links().
 *
 * Adds the "View my topics" link to the user menu.
 */
function social_topic_social_user_account_header_account_links(array $context) {

  // We require a user for this link.
  if (empty($context['user']) || !$context['user'] instanceof AccountInterface) {
    return [];
  }
  return [
    'my_topics' => [
      '#type' => 'link',
      '#attributes' => [
        'title' => new TranslatableMarkup('View my topics'),
      ],
      '#title' => new TranslatableMarkup('My topics'),
      '#weight' => 700,
    ] + Url::fromRoute('view.topics.page_profile', [
      'user' => $context['user']
        ->id(),
    ])
      ->toRenderArray(),
  ];
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function social_topic_form_node_topic_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  social_topic_widget_alter($form);
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function social_topic_form_node_topic_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  social_topic_widget_alter($form);
}

/**
 * Function that does some magic to the event type field.
 *
 * @param array $form
 *   Form array.
 */
function social_topic_widget_alter(array &$form) {

  /** @var \Drupal\Core\Config\ImmutableConfig $config */
  $config = \Drupal::config('social_topic.settings');

  // Change the widget if more than X.
  if (count($form['field_topic_type']['widget']['#options']) >= $config
    ->get('social_topic_type_select_changer')) {
    $form['field_topic_type']['widget']['#type'] = 'select';
  }
}

/**
 * Custom permission check, to see if people have access to users' topics.
 *
 * Implements hook_block_access().
 */
function social_topic_block_access(Block $block, $operation, AccountInterface $account) {
  if ($operation === 'view' && ($block
    ->getPluginId() === 'views_exposed_filter_block:topics-page_profile' || $block
    ->getPluginId() === 'views_block:topics-block_user_topics')) {

    // Here we're going to assume by default access is not granted.
    $topicController = SocialTopicController::create(\Drupal::getContainer());
    $access = $topicController
      ->myTopicAccess($account);

    // If the 'myTopicAccess' returns 'AccessResultNeutral', we have to assume
    // that access must be denied.
    if ($access instanceof AccessResultNeutral) {

      // Return forbidden, since access was not explicitly granted.
      return AccessResult::forbidden();
    }
    return $access;
  }

  // No opinion.
  return AccessResult::neutral();
}

/**
 * Implements hook_social_follow_content_types_alter().
 */
function social_topic_social_follow_content_types_alter(array &$types) {
  $types[] = 'topic';
}