comments_order.module in Comments Order 8
Contains comments_order.module.
File
comments_order.moduleView source
<?php
/**
* @file
* Contains comments_order.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_help().
*/
function comments_order_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the comments_order module.
case 'help.page.comments_order':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('This module allows to set order for node comments') . '</p>';
return $output;
}
}
/**
* Implements hook_query_TAG_alter() for comment_filter tag.
*/
function comments_order_query_comment_filter_alter(AlterableInterface $query) {
// Change comment order to DESC for 'comment' field.
if ($query
->getMetaData('base_table') == 'comment') {
/** @var \Drupal\Core\Database\Query\SelectInterface $query */
$order_by =& $query
->getOrderBy();
$expression =& $query
->getExpressions();
/** @var \Drupal\Core\Entity\Entity $entity */
$entity = $query
->getMetaData('entity');
/** @var \Drupal\field\Entity\FieldConfig $field */
$field = FieldConfig::loadByName($entity
->getEntityTypeId(), $entity
->bundle(), $query
->getMetaData('field_name'));
// Set reverse order if checked.
$field_order = $field
->getThirdPartySetting('comments_order', 'order', 'ASC');
if (substr($field_order, 0, 4) == 'DESC') {
// 'c.cid' is for flat comment lists.
if (isset($order_by['c.cid']) && substr($order_by['c.cid'], 0, 3) == 'ASC') {
// Reverse order.
$order_by['c.cid'] = 'DESC';
}
// 'torder' is for threaded comment lists.
if (isset($order_by['torder']) && substr($order_by['torder'], 0, 3) == 'ASC') {
if (!$field
->getThirdPartySetting('comments_order', 'children_natural_order', 1)) {
// Reverse order for parent comments.
// And reverse order for children comments.
// EXPLANATION of '.z':
// The 'thread' field is string like '10.01.12f'.
// Each part of it is generated by Number::intToAlphadecimal.
// See core/lib/Drupal/Component/Utility/Number.php.
// This function returns string followed by character.
// This character is finite:
// Maximum integer value on a 64-bit system is 9223372036854775807.
// In higher code variable $num will be '1y2p0ij32e8e7'.
// And variable $length will be 13. Expression ord('0') is 48.
// Therefore first character can be 60 at maximum.
// For reverse sorting we need to add first heavy character,
// For parent comment thread string.
// If use previous logic the character 'z' will be always heaviest,
// Than other available children thread string.
// For each comment thread we add '.z' and sort by it.
$expression['torder']['expression'] = 'SUBSTRING_INDEX(SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1)), \'.\', 1)';
$order_by['torder'] = 'DESC';
$query
->addExpression('CONCAT(SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1)), \'.z\')', 'torderchild');
$query
->orderBy('torderchild', 'DESC');
}
else {
// Reverse order for parent comments.
// And natural order for children comments.
// Children comments are sorted like default.
$expression['torder']['expression'] = 'SUBSTRING_INDEX(SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1)), \'.\', 1)';
$order_by['torder'] = 'DESC';
$query
->addExpression('SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))', 'torderchild');
$query
->orderBy('torderchild', 'ASC');
}
}
}
}
}
/**
* Implements hook_form_alter().
*/
function comments_order_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Alter 'field_config_edit_form' form.
if ($form_id == 'field_config_edit_form') {
/** @var \Drupal\field\Entity\FieldConfig $field */
$field = $form_state
->getFormObject()
->getEntity();
// Alter only for comments field.
if ($field
->getType() == 'comment') {
// Order field.
$form['order'] = [
'#type' => 'select',
'#title' => t('Comments order'),
'#options' => [
'ASC' => t('Oldest first (ascending order)'),
'DESC' => t('Newest first (descending order)'),
],
'#default_value' => $field
->getThirdPartySetting('comments_order', 'order', 'ASC'),
'#weight' => 10,
];
// Children order field.
$form['children_natural_order'] = [
'#type' => 'checkbox',
'#title' => t('Natural order for children'),
'#default_value' => $field
->getThirdPartySetting('comments_order', 'children_natural_order', 1),
'#states' => [
'visible' => [
'select[name="order"]' => [
'value' => 'DESC',
],
],
],
'#weight' => 11,
];
// Add entity builder.
$form['#entity_builders'][] = '_comments_order_field_config_edit_form_builder';
}
}
elseif (strpos($form['#id'], 'comment-form') === 0) {
// Add entity builder.
$form['actions']['submit']['#submit'][] = '_comments_order_comment_form_submit';
}
}
/**
* Comments order form builder to map values to third party settings.
*/
function _comments_order_field_config_edit_form_builder($entity_type, FieldConfig $field, &$form, FormStateInterface $form_state) {
// Save settings.
$field
->setThirdPartySetting('comments_order', 'order', $form_state
->getValue('order'));
$field
->setThirdPartySetting('comments_order', 'children_natural_order', $form_state
->getValue('children_natural_order'));
}
/**
* Comment form builder to alter redirect.
*/
function _comments_order_comment_form_submit($form, FormStateInterface $form_state) {
/** @var \Drupal\comment\Entity\Comment $comment */
$comment = $form_state
->getFormObject()
->getEntity();
/** @var \Drupal\Core\Entity\Entity $entity */
$entity = $comment
->getCommentedEntity();
/** @var \Drupal\field\Entity\FieldConfig $field */
$field = FieldConfig::loadByName($entity
->getEntityTypeId(), $entity
->bundle(), $comment
->getFieldName());
// Redirect to the first page after comment submition if set reverse order.
if ($field
->getThirdPartySetting('comments_order', 'order', 'ASC') == 'DESC' && \Drupal::request()
->isXmlHttpRequest() == FALSE) {
// Redirect to the first page after comment submition.
$uri = $form_state
->getRedirect();
$uri
->setOption('query', []);
$form_state
->setRedirectUrl($uri);
}
}
Functions
Name![]() |
Description |
---|---|
comments_order_form_alter | Implements hook_form_alter(). |
comments_order_help | Implements hook_help(). |
comments_order_query_comment_filter_alter | Implements hook_query_TAG_alter() for comment_filter tag. |
_comments_order_comment_form_submit | Comment form builder to alter redirect. |
_comments_order_field_config_edit_form_builder | Comments order form builder to map values to third party settings. |