Newer
Older
Dries Buytaert
committed
* Provides discussion forums.
use Drupal\comment\CommentInterface;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
Angie Byron
committed
use Drupal\Component\Utility\Xss;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Component\Utility\String;
Dries Buytaert
committed
use Drupal\Core\Form\FormStateInterface;
Angie Byron
committed
use Drupal\Core\Routing\RouteMatchInterface;
Dries Buytaert
committed
/**
Dries Buytaert
committed
* Implements hook_help().
Dries Buytaert
committed
*/
Angie Byron
committed
function forum_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.forum':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Forum module lets you create threaded discussion forums with functionality similar to other message board systems. Forums are useful because they allow community members to discuss topics with one another while ensuring those conversations are archived for later reference. In a forum, users post topics and threads in nested hierarchies, allowing discussions to be categorized and grouped. The forum hierarchy consists of:') . '</p>';
$output .= '<ul>';
$output .= '<li>' . t('Optional containers (for example, <em>Support</em>), which can hold:') . '</li>';
$output .= '<ul><li>' . t('Forums (for example, <em>Installing Drupal</em>), which can hold:') . '</li>';
$output .= '<ul><li>' . t('Forum topics submitted by users (for example, <em>How to start a Drupal 6 Multisite</em>), which start discussions and are starting points for:') . '</li>';
$output .= '<ul><li>' . t('Threaded comments submitted by users (for example, <em>You have these options...</em>).') . '</li>';
$output .= '</ul>';
$output .= '</ul>';
$output .= '</ul>';
$output .= '</ul>';
Alex Pott
committed
$output .= '<p>' . t('For more information, see <a href="!forum">the online documentation for the Forum module</a>.', array('!forum' => 'https://drupal.org/documentation/modules/forum')) . '</p>';
Angie Byron
committed
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Setting up forum structure') . '</dt>';
Alex Pott
committed
$output .= '<dd>' . t('Visit the <a href="!forums">Forums page</a> to set up containers and forums to hold your discussion topics.', array('!forums' => \Drupal::url('forum.overview'))) . '</dd>';
$output .= '<dt>' . t('Starting a discussion') . '</dt>';
Angie Byron
committed
$output .= '<dd>' . t('The <a href="!create-topic">Forum topic</a> link on the <a href="!content-add">Add content</a> page creates the first post of a new threaded discussion, or thread.', array('!create-topic' => \Drupal::url('node.add', array('node_type' => 'forum')), '!content-add' => \Drupal::url('node.add_page'))) . '</dd>';
Alex Pott
committed
$output .= '<dt>' . t('Navigating in the Forum') . '</dt>';
$output .= '<dd>' . t('Enabling the Forum module provides a default <em>Forums</em> menu item in the Tools menu that links to the <a href="!forums">Forums page</a>.', array('!forums' => \Drupal::url('forum.index'))) . '</dd>';
Angie Byron
committed
$output .= '<dt>' . t('Moving forum topics') . '</dt>';
$output .= '<dd>' . t('A forum topic (and all of its comments) may be moved between forums by selecting a different forum while editing a forum topic. When moving a forum topic between forums, the <em>Leave shadow copy</em> option creates a link in the original forum pointing to the new location.') . '</dd>';
$output .= '<dt>' . t('Locking and disabling comments') . '</dt>';
$output .= '<dd>' . t('Selecting <em>Closed</em> under <em>Comment settings</em> while editing a forum topic will lock (prevent new comments on) the thread. Selecting <em>Hidden</em> under <em>Comment settings</em> while editing a forum topic will hide all existing comments on the thread, and prevent new ones.') . '</dd>';
Angie Byron
committed
$output .= '</dl>';
Dries Buytaert
committed
return $output;
case 'forum.overview':
Angie Byron
committed
$output = '<p>' . t('Forums contain forum topics. Use containers to group related forums.') . '</p>';
$more_help_link = array(
'#type' => 'link',
'#route_name' => 'help.page',
'#route_parameters' => array('name' => 'forum'),
'#title' => t('More help'),
);
$container = array(
'#theme' => 'container',
'#children' => drupal_render($more_help_link),
'#attributes' => array(
'class' => array('more-help-link'),
),
);
Angie Byron
committed
$output .= drupal_render($container);
Angie Byron
committed
return $output;
case 'forum.add_container':
Angie Byron
committed
return '<p>' . t('Use containers to group related forums.') . '</p>';
case 'forum.add_forum':
Angie Byron
committed
return '<p>' . t('A forum holds related forum topics.') . '</p>';
case 'forum.settings':
Alex Pott
committed
return '<p>' . t('Adjust the display of your forum topics. Organize the forums on the <a href="!forum-structure">forum structure page</a>.', array('!forum-structure' => \Drupal::url('forum.overview'))) . '</p>';
Dries Buytaert
committed
/**
Dries Buytaert
committed
* Implements hook_theme().
Dries Buytaert
committed
*/
function forum_theme() {
return array(
Dries Buytaert
committed
'forums' => array(
'template' => 'forums',
'variables' => array('forums' => array(), 'topics' => array(), 'topics_pager' => array(), 'parents' => NULL, 'term' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL, 'header' => array()),
Dries Buytaert
committed
),
'forum_list' => array(
'template' => 'forum-list',
'variables' => array('forums' => NULL, 'parents' => NULL, 'tid' => NULL),
Dries Buytaert
committed
),
'forum_icon' => array(
'template' => 'forum-icon',
'variables' => array('new_posts' => NULL, 'num_posts' => 0, 'comment_mode' => 0, 'sticky' => 0, 'first_new' => FALSE),
Dries Buytaert
committed
),
Dries Buytaert
committed
'forum_submitted' => array(
'template' => 'forum-submitted',
'variables' => array('topic' => NULL),
),
Dries Buytaert
committed
);
}
Dries Buytaert
committed
/**
* Implements hook_menu_local_tasks().
Dries Buytaert
committed
*/
Angie Byron
committed
function forum_menu_local_tasks(&$data, $route_name) {
$user = \Drupal::currentUser();
Dries Buytaert
committed
Angie Byron
committed
// Add action link to 'node/add/forum' on 'forum' sub-pages.
Angie Byron
committed
if (in_array($route_name, array('forum.index', 'forum.page'))) {
$forum_term = \Drupal::routeMatch()->getParameter('taxonomy_term');
$vid = \Drupal::config('forum.settings')->get('vocabulary');
$links = array();
// Loop through all bundles for forum taxonomy vocabulary field.
Alex Pott
committed
$field_map = \Drupal::entityManager()->getFieldMap();
foreach ($field_map['node']['taxonomy_forums']['bundles'] as $type) {
if (\Drupal::entityManager()->getAccessControlHandler('node')->createAccess($type)) {
$links[$type] = array(
'#theme' => 'menu_local_action',
'#link' => array(
'title' => t('Add new @node_type', array('@node_type' => entity_load('node_type', $type)->label())),
'href' => 'node/add/' . $type,
),
);
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();
Dries Buytaert
committed
}
}
}
if (empty($links)) {
// Authenticated user does not have access to create new topics.
if ($user->isAuthenticated()) {
$links['disallowed'] = array(
'#theme' => 'menu_local_action',
'#link' => array(
'title' => t('You are not allowed to post new content in the forum.'),
),
);
}
// Anonymous user does not have access to create new topics.
else {
$links['login'] = array(
'#theme' => 'menu_local_action',
'#link' => array(
'title' => t('<a href="@login">Log in</a> to post new content in the forum.', array(
'@login' => url('user/login', array('query' => drupal_get_destination())),
)),
'localized_options' => array('html' => TRUE),
),
);
Dries Buytaert
committed
}
}
$data['actions'] += $links;
Dries Buytaert
committed
}
}
Dries Buytaert
committed
Dries Buytaert
committed
/**
* Implements hook_entity_type_build().
Dries Buytaert
committed
*/
function forum_entity_type_build(array &$entity_types) {
/** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
Alex Pott
committed
// Register forum specific forms.
$entity_types['taxonomy_term']
Alex Pott
committed
->setFormClass('forum', 'Drupal\forum\Form\ForumForm')
->setFormClass('container', 'Drupal\forum\Form\ContainerForm')
Alex Pott
committed
->setLinkTemplate('forum-delete-form', 'forum.delete')
->setLinkTemplate('forum-edit-form', 'forum.edit_forum');
Dries Buytaert
committed
}
Dries Buytaert
committed
/**
Dries Buytaert
committed
* Implements hook_entity_bundle_info_alter().
Dries Buytaert
committed
*/
Dries Buytaert
committed
function forum_entity_bundle_info_alter(&$bundles) {
// Take over URI construction for taxonomy terms that are forums.
if ($vid = \Drupal::config('forum.settings')->get('vocabulary')) {
Dries Buytaert
committed
if (isset($bundles['taxonomy_term'][$vid])) {
$bundles['taxonomy_term'][$vid]['uri_callback'] = 'forum_uri';
Dries Buytaert
committed
}
}
}
/**
Dries Buytaert
committed
* Entity URI callback used in forum_entity_bundle_info_alter().
Dries Buytaert
committed
*/
function forum_uri($forum) {
return array(
Alex Pott
committed
'route_name' => 'forum.page',
'route_parameters' => array(
'taxonomy_term' => $forum->id(),
),
Dries Buytaert
committed
);
}
Dries Buytaert
committed
/**
Dries Buytaert
committed
* Implements hook_node_validate().
*
Jennifer Hodgdon
committed
* Checks in particular that the node is assigned only a "leaf" term in the
* forum taxonomy.
Dries Buytaert
committed
*/
Dries Buytaert
committed
function forum_node_validate(EntityInterface $node, $form, FormStateInterface $form_state) {
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
Dries Buytaert
committed
// vocabulary is selected, not a "container" term.
catch
committed
if (!$node->taxonomy_forums->isEmpty()) {
Dries Buytaert
committed
// Extract the node's proper topic ID.
catch
committed
foreach ($node->taxonomy_forums as $delta => $item) {
Angie Byron
committed
// If no term was selected (e.g. when no terms exist yet), remove the
// item.
catch
committed
if (empty($item->target_id)) {
unset($node->taxonomy_forums[$delta]);
Angie Byron
committed
continue;
}
catch
committed
$term = $item->entity;
Dries Buytaert
committed
if (!$term) {
Alex Pott
committed
$form_state->setErrorByName('taxonomy_forums', t('Select a forum.'));
Dries Buytaert
committed
continue;
}
catch
committed
$used = \Drupal::entityQuery('taxonomy_term')
->condition('tid', $term->id())
->condition('vid', $term->bundle())
->range(0, 1)
->count()
->execute();
if ($used && !empty($term->forum_container->value)) {
Alex Pott
committed
$form_state->setErrorByName('taxonomy_forums', t('The item %forum is a forum container, not a forum. Select one of the forums below instead.', array('%forum' => $term->getName())));
Dries Buytaert
committed
}
}
Dries Buytaert
committed
}
}
}
Dries Buytaert
committed
Dries Buytaert
committed
/**
* Implements hook_ENTITY_TYPE_presave() for node entities.
Dries Buytaert
committed
*
Jennifer Hodgdon
committed
* Assigns the forum taxonomy when adding a topic from within a forum.
Dries Buytaert
committed
*/
Angie Byron
committed
function forum_node_presave(EntityInterface $node) {
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
Dries Buytaert
committed
// Make sure all fields are set properly:
$node->icon = !empty($node->icon) ? $node->icon : '';
catch
committed
if (!$node->taxonomy_forums->isEmpty()) {
$node->forum_tid = $node->taxonomy_forums->target_id;
// Only do a shadow copy check if this is not a new node.
if (!$node->isNew()) {
$old_tid = \Drupal::service('forum.index_storage')->getOriginalTermId($node);
if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) {
// A shadow copy needs to be created. Retain new term and add old term.
catch
committed
$node->taxonomy_forums[count($node->taxonomy_forums)] = array('target_id' => $old_tid);
}
Dries Buytaert
committed
}
}
}
}
Gábor Hojtsy
committed
Dries Buytaert
committed
/**
* Implements hook_ENTITY_TYPE_update() for node entities.
Dries Buytaert
committed
*/
Angie Byron
committed
function forum_node_update(EntityInterface $node) {
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
Angie Byron
committed
// If this is not a new revision and does exist, update the forum record,
// otherwise insert a new one.
/** @var \Drupal\forum\ForumIndexStorageInterface $forum_index_storage */
$forum_index_storage = \Drupal::service('forum.index_storage');
if ($node->getRevisionId() == $node->original->getRevisionId() && $forum_index_storage->getOriginalTermId($node)) {
Angie Byron
committed
if (!empty($node->forum_tid)) {
$forum_index_storage->update($node);
Dries Buytaert
committed
}
// The node is removed from the forum.
else {
$forum_index_storage->delete($node);
Dries Buytaert
committed
}
}
else {
Angie Byron
committed
if (!empty($node->forum_tid)) {
$forum_index_storage->create($node);
Gábor Hojtsy
committed
}
Dries Buytaert
committed
}
Angie Byron
committed
// If the node has a shadow forum topic, update the record for this
// revision.
Dries Buytaert
committed
if (!empty($node->shadow)) {
$forum_index_storage->deleteRevision($node);
$forum_index_storage->create($node);
}
// If the node is published, update the forum index.
if ($node->isPublished()) {
$forum_index_storage->deleteIndex($node);
$forum_index_storage->createIndex($node);
}
// When a forum node is unpublished, remove it from the forum_index table.
else {
$forum_index_storage->deleteIndex($node);
Dries Buytaert
committed
}
}
Gábor Hojtsy
committed
Dries Buytaert
committed
/**
* Implements hook_ENTITY_TYPE_insert() for node entities.
Dries Buytaert
committed
*/
Angie Byron
committed
function forum_node_insert(EntityInterface $node) {
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
/** @var \Drupal\forum\ForumIndexStorageInterface $forum_index_storage */
$forum_index_storage = \Drupal::service('forum.index_storage');
Angie Byron
committed
if (!empty($node->forum_tid)) {
$forum_index_storage->create($node);
Dries Buytaert
committed
}
// If the node is published, update the forum index.
if ($node->isPublished()) {
$forum_index_storage->createIndex($node);
Dries Buytaert
committed
}
}
Gábor Hojtsy
committed
Dries Buytaert
committed
/**
* Implements hook_ENTITY_TYPE_predelete() for node entities.
Dries Buytaert
committed
*/
Angie Byron
committed
function forum_node_predelete(EntityInterface $node) {
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
/** @var \Drupal\forum\ForumIndexStorageInterface $forum_index_storage */
$forum_index_storage = \Drupal::service('forum.index_storage');
$forum_index_storage->delete($node);
$forum_index_storage->deleteIndex($node);
Dries Buytaert
committed
}
Dries Buytaert
committed
}
Dries Buytaert
committed
Dries Buytaert
committed
/**
* Implements hook_ENTITY_TYPE_storage_load() for node entities.
Dries Buytaert
committed
*/
function forum_node_storage_load($nodes) {
$node_vids = array();
foreach ($nodes as $node) {
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
$node_vids[] = $node->getRevisionId();
}
}
if (!empty($node_vids)) {
$result = \Drupal::service('forum.index_storage')->read($node_vids);
foreach ($result as $record) {
$nodes[$record->nid]->forum_tid = $record->tid;
}
Dries Buytaert
committed
}
Dries Buytaert
committed
/**
Dries Buytaert
committed
* Implements hook_permission().
Dries Buytaert
committed
*/
function forum_permission() {
$perms = array(
Angie Byron
committed
'administer forums' => array(
'title' => t('Administer forums'),
),
);
return $perms;
Angie Byron
committed
/**
* Implements hook_ENTITY_TYPE_update() for comment entities.
Angie Byron
committed
*/
function forum_comment_update(CommentInterface $comment) {
Alex Pott
committed
if ($comment->getCommentedEntityTypeId() == 'node') {
\Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity());
Angie Byron
committed
}
}
/**
* Implements hook_ENTITY_TYPE_insert() for comment entities.
Angie Byron
committed
*/
Alex Pott
committed
function forum_comment_insert(CommentInterface $comment) {
if ($comment->getCommentedEntityTypeId() == 'node') {
\Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity());
Angie Byron
committed
}
/**
* Implements hook_ENTITY_TYPE_delete() for comment entities.
Angie Byron
committed
*/
function forum_comment_delete(CommentInterface $comment) {
if ($comment->getCommentedEntityTypeId() == 'node') {
\Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity());
Angie Byron
committed
}
Gerhard Killesreiter
committed
/**
* Implements hook_form_BASE_FORM_ID_alter().
Gerhard Killesreiter
committed
*/
Dries Buytaert
committed
function forum_form_taxonomy_vocabulary_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$vid = \Drupal::config('forum.settings')->get('vocabulary');
$vocabulary = $form_state['controller']->getEntity();
if ($vid == $vocabulary->id()) {
$form['help_forum_vocab'] = array(
'#markup' => t('This is the designated forum vocabulary. Some of the normal vocabulary options have been removed.'),
'#weight' => -1,
);
// Forum's vocabulary always has single hierarchy. Forums and containers
// have only one parent or no parent for root items. By default this value
// is 0.
$form['hierarchy']['#value'] = TAXONOMY_HIERARCHY_SINGLE;
// Do not allow to delete forum's vocabulary.
$form['actions']['delete']['#access'] = FALSE;
// Do not allow to change a vid of forum's vocabulary.
$form['vid']['#disabled'] = TRUE;
}
}
/**
* Implements hook_form_FORM_ID_alter() for taxonomy_term_form().
*/
Dries Buytaert
committed
function forum_form_taxonomy_term_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$vid = \Drupal::config('forum.settings')->get('vocabulary');
if (isset($form['vid']['#value']) && $form['vid']['#value'] == $vid) {
Gábor Hojtsy
committed
// Hide multiple parents select from forum terms.
$form['relations']['parent']['#access'] = FALSE;
Gábor Hojtsy
committed
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter() for node_form().
*/
Dries Buytaert
committed
function forum_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$node = $form_state['controller']->getEntity();
if (isset($node->taxonomy_forums) && !$node->isNew()) {
$forum_terms = $node->taxonomy_forums;
// If editing, give option to leave shadows.
$shadow = (count($forum_terms) > 1);
$form['shadow'] = array(
'#type' => 'checkbox',
'#title' => t('Leave shadow copy'),
'#default_value' => $shadow,
'#description' => t('If you move this topic, you can leave a link in the old forum to the new forum.'),
);
$form['forum_tid'] = array('#type' => 'value', '#value' => $node->forum_tid);
}
if (isset($form['taxonomy_forums'])) {
Angie Byron
committed
$widget =& $form['taxonomy_forums']['widget'];
Gábor Hojtsy
committed
// Make the vocabulary required for 'real' forum-nodes.
Angie Byron
committed
$widget['#required'] = TRUE;
$widget['#multiple'] = FALSE;
if (empty($widget['#default_value'])) {
Dries Buytaert
committed
// If there is no default forum already selected, try to get the forum
// ID from the URL (e.g., if we are on a page like node/add/forum/2, we
// expect "2" to be the ID of the forum that was requested).
Alex Pott
committed
$requested_forum_id = \Drupal::request()->query->get('forum_id');
Angie Byron
committed
$widget['#default_value'] = is_numeric($requested_forum_id) ? $requested_forum_id : '';
Dries Buytaert
committed
}
Gábor Hojtsy
committed
}
Gerhard Killesreiter
committed
}
/**
Angie Byron
committed
* Implements hook_preprocess_HOOK() for block templates.
*/
function forum_preprocess_block(&$variables) {
Alex Pott
committed
if ($variables['configuration']['provider'] == 'forum') {
Dries Buytaert
committed
$variables['attributes']['role'] = 'navigation';
}
}
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
/**
* Implements hook_theme_suggestions_HOOK().
*/
function forum_theme_suggestions_forums(array $variables) {
$suggestions = array();
$tid = $variables['term']->id();
// Provide separate template suggestions based on what's being output. Topic
// ID is also accounted for. Check both variables to be safe then the inverse.
// Forums with topic IDs take precedence.
if ($variables['forums'] && !$variables['topics']) {
$suggestions[] = 'forums__containers';
$suggestions[] = 'forums__' . $tid;
$suggestions[] = 'forums__containers__' . $tid;
}
elseif (!$variables['forums'] && $variables['topics']) {
$suggestions[] = 'forums__topics';
$suggestions[] = 'forums__' . $tid;
$suggestions[] = 'forums__topics__' . $tid;
}
else {
$suggestions[] = 'forums__' . $tid;
}
return $suggestions;
}
* Prepares variables for forums templates.
*
* Default template: forums.html.twig.
*
* @param array $variables
Jennifer Hodgdon
committed
* An array containing the following elements:
* - forums: An array of all forum objects to display for the given taxonomy
* term ID. If tid = 0 then all the top-level forums are displayed.
* - topics: An array of all the topics in the current forum.
* - parents: An array of taxonomy term objects that are ancestors of the
* current term ID.
* - term: Taxonomy term of the current forum.
Jennifer Hodgdon
committed
* - sortby: One of the following integers indicating the sort criteria:
* - 1: Date - newest first.
* - 2: Date - oldest first.
* - 3: Posts with the most comments first.
* - 4: Posts with the least comments first.
* - forum_per_page: The maximum number of topics to display per page.
Dries Buytaert
committed
function template_preprocess_forums(&$variables) {
$variables['tid'] = $variables['term']->id();
if ($variables['forums_defined'] = count($variables['forums']) || count($variables['parents'])) {
if (!empty($variables['forums'])) {
$variables['forums'] = array(
'#theme' => 'forum_list',
'#forums' => $variables['forums'],
'#parents' => $variables['parents'],
'#tid' => $variables['tid'],
);
}
Angie Byron
committed
if ($variables['term'] && empty($variables['term']->forum_container->value) && !empty($variables['topics'])) {
$forum_topic_list_header = $variables['header'];
Angie Byron
committed
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
$table = array(
'#theme' => 'table__forum_topic_list',
'#responsive' => FALSE,
'#attributes' => array('id' => 'forum-topic-' . $variables['tid']),
'#header' => array(),
'#rows' => array(),
);
if (!empty($forum_topic_list_header)) {
$table['#header'] = $forum_topic_list_header;
}
/** @var \Drupal\node\NodeInterface $topic */
foreach ($variables['topics'] as $id => $topic) {
$variables['topics'][$id]->icon = array(
'#theme' => 'forum_icon',
'#new_posts' => $topic->new,
'#num_posts' => $topic->comment_count,
'#comment_mode' => $topic->comment_mode,
'#sticky' => $topic->isSticky(),
'#first_new' => $topic->first_new,
);
// We keep the actual tid in forum table, if it's different from the
// current tid then it means the topic appears in two forums, one of
// them is a shadow copy.
if ($variables['tid'] != $topic->forum_tid) {
$variables['topics'][$id]->moved = TRUE;
$variables['topics'][$id]->title = String::checkPlain($topic->getTitle());
Angie Byron
committed
$variables['topics'][$id]->message = l(t('This topic has been moved'), "forum/$topic->forum_tid");
}
else {
$variables['topics'][$id]->moved = FALSE;
$variables['topics'][$id]->title_link = l($topic->getTitle(), 'node/' . $topic->id());
$variables['topics'][$id]->message = '';
}
$forum_submitted = array('#theme' => 'forum_submitted', '#topic' => (object) array(
'uid' => $topic->getOwnerId(),
'name' => $topic->getOwner()->getUsername(),
'created' => $topic->getCreatedTime(),
));
$variables['topics'][$id]->submitted = drupal_render($forum_submitted);
$forum_submitted = array(
'#theme' => 'forum_submitted',
'#topic' => isset($topic->last_reply) ? $topic->last_reply : NULL,
);
$variables['topics'][$id]->last_reply = drupal_render($forum_submitted);
$variables['topics'][$id]->new_text = '';
$variables['topics'][$id]->new_url = '';
if ($topic->new_replies) {
$page_number = \Drupal::entityManager()->getStorage('comment')
->getNewCommentPageNumber($topic->comment_count, $topic->new_replies, $topic, 'comment_forum');
$query = $page_number ? array('page' => $page_number) : NULL;
Angie Byron
committed
$variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new post<span class="visually-hidden"> in topic %title</span>', '@count new posts<span class="visually-hidden"> in topic %title</span>', array('%title' => $variables['topics'][$id]->label()));
$variables['topics'][$id]->new_url = url('node/' . $topic->id(), array('query' => $query, 'fragment' => 'new'));
Angie Byron
committed
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
}
// Build table rows from topics.
$row = array();
$row[] = array(
'data' => array(
$topic->icon,
array(
'#markup' => '<div class="title"><div>' . $topic->title_link . '</div><div>' . $topic->submitted . '</div></div>',
),
),
'class' => array('topic'),
);
if ($topic->moved) {
$row[] = array(
'data' => $topic->message,
'colspan' => '2',
);
}
else {
$new_replies = '';
if ($topic->new_replies) {
$new_replies = '<br /><a href="' . $topic->new_url . '">' . $topic->new_text . '</a>';
}
$row[] = array(
'data' => $topic->comment_count . $new_replies,
'class' => array('replies'),
);
$row[] = array(
'data' => $topic->last_reply,
'class' => array('last-reply'),
);
}
$table['#rows'][] = $row;
}
$variables['topics'] = $table;
$variables['topics_pager'] = array(
'#theme' => 'pager',
);
* Prepares variables for forum list templates.
* Default template: forum-list.html.twig.
*
* @param array $variables
Jennifer Hodgdon
committed
* An array containing the following elements:
* - forums: An array of all forum objects to display for the given taxonomy
* term ID. If tid = 0 then all the top-level forums are displayed.
* - parents: An array of taxonomy term objects that are ancestors of the
* current term ID.
* - tid: Taxonomy term ID of the current forum.
function template_preprocess_forum_list(&$variables) {
$user = \Drupal::currentUser();
// Sanitize each forum so that the template can safely print the data.
foreach ($variables['forums'] as $id => $forum) {
Angie Byron
committed
$variables['forums'][$id]->description = Xss::filterAdmin($forum->description->value);
$variables['forums'][$id]->link = url("forum/" . $forum->id());
$variables['forums'][$id]->name = String::checkPlain($forum->label());
$variables['forums'][$id]->is_container = !empty($forum->forum_container->value);
$variables['forums'][$id]->zebra = $row % 2 == 0 ? 'odd' : 'even';
$row++;
$variables['forums'][$id]->new_text = '';
$variables['forums'][$id]->new_url = '';
$variables['forums'][$id]->new_topics = 0;
$variables['forums'][$id]->old_topics = $forum->num_topics;
Angie Byron
committed
$variables['forums'][$id]->icon_class = 'default';
$variables['forums'][$id]->icon_title = t('No new posts');
Dries Buytaert
committed
if ($user->isAuthenticated()) {
$variables['forums'][$id]->new_topics = \Drupal::service('forum_manager')->unreadTopics($forum->id(), $user->id());
if ($variables['forums'][$id]->new_topics) {
$variables['forums'][$id]->new_text = format_plural($variables['forums'][$id]->new_topics, '1 new post<span class="visually-hidden"> in forum %title</span>', '@count new posts<span class="visually-hidden"> in forum %title</span>', array('%title' => $variables['forums'][$id]->label()));
$variables['forums'][$id]->new_url = url('forum/' . $forum->id(), array('fragment' => 'new'));
Angie Byron
committed
$variables['forums'][$id]->icon_class = 'new';
$variables['forums'][$id]->icon_title = t('New posts');
$variables['forums'][$id]->old_topics = $forum->num_topics - $variables['forums'][$id]->new_topics;
$forum_submitted = array('#theme' => 'forum_submitted', '#topic' => $forum->last_post);
$variables['forums'][$id]->last_reply = drupal_render($forum_submitted);
$variables['pager'] = array(
'#theme' => 'pager',
);
// Give meaning to $tid for themers. $tid actually stands for term ID.
Gábor Hojtsy
committed
$variables['forum_id'] = $variables['tid'];
unset($variables['tid']);
/**
* Prepares variables for forum icon templates.
*
* Default template: forum-icon.html.twig.
*
* @param array $variables
Jennifer Hodgdon
committed
* An array containing the following elements:
* - new_posts: Indicates whether or not the topic contains new posts.
* - num_posts: The total number of posts in all topics.
* - comment_mode: An integer indicating whether comments are open, closed,
* or hidden.
* - sticky: Indicates whether the topic is sticky.
* - first_new: Indicates whether this is the first topic with new posts.
*/
function template_preprocess_forum_icon(&$variables) {
$variables['hot_threshold'] = \Drupal::config('forum.settings')->get('topics.hot_threshold');
if ($variables['num_posts'] > $variables['hot_threshold']) {
$icon_status_class = $variables['new_posts'] ? 'hot-new' : 'hot';
Dries Buytaert
committed
$variables['icon_title'] = $variables['new_posts'] ? t('Hot topic, new comments') : t('Hot topic');
$icon_status_class = $variables['new_posts'] ? 'new' : 'default';
Dries Buytaert
committed
$variables['icon_title'] = $variables['new_posts'] ? t('New comments') : t('Normal topic');
if ($variables['comment_mode'] == CommentItemInterface::CLOSED || $variables['comment_mode'] == CommentItemInterface::HIDDEN) {
$icon_status_class = 'closed';
Dries Buytaert
committed
$variables['icon_title'] = t('Closed topic');
}
if ($variables['sticky'] == 1) {
$icon_status_class = 'sticky';
Dries Buytaert
committed
$variables['icon_title'] = t('Sticky topic');
}
$variables['attributes']['class'][] = 'icon';
$variables['attributes']['class'][] = 'topic-status-' . $icon_status_class;
$variables['attributes']['title'] = $variables['icon_title'];
Dries Buytaert
committed
}
/**
* Prepares variables for forum submission information templates.
Jennifer Hodgdon
committed
*
* The submission information will be displayed in the forum list and topic
* list.
*
* Default template: forum-submitted.html.twig.
*
* @param array $variables
Jennifer Hodgdon
committed
* An array containing the following elements:
* - topic: The topic object.
*/
Dries Buytaert
committed
function template_preprocess_forum_submitted(&$variables) {
$variables['author'] = '';
if (isset($variables['topic']->uid)) {
$username = array('#theme' => 'username', '#account' => user_load($variables['topic']->uid));
$variables['author'] = drupal_render($username);
}
Alex Pott
committed
$variables['time'] = isset($variables['topic']->created) ? \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $variables['topic']->created) : '';