You are here

function comments_order_query_comment_filter_alter in Comments Order 8

Implements hook_query_TAG_alter() for comment_filter tag.

File

./comments_order.module, line 30
Contains comments_order.module.

Code

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');
        }
      }
    }
  }
}